cancel
Showing results for 
Search instead for 
Did you mean: 

STM32WB55 MAC 802.15.4 Standby Mode Wake-Up Issue After MX_APPE_Init – Need Help Debugging RTC Wake-Up

YBAYR.1
Associate III

I am working on an example project: MAC 802 (\STM32Cube\Repository\STM32Cube_FW_WB_V1.21.0\Projects\P-NUCLEO-WB55.Nucleo\Applications\Mac_802_15_4\Mac_802_15_4_Node).
I have added standby mode to this code, but I am unable to wake it up.
After entering standby using RTC, the system does not wake up after MX_APPE_Init();.
My code is as follows:

int main(void)
{
  /* Initialize the HAL */
  HAL_Init();

  Check_Wakeup_Source();

  ALGORTM.WakeUp_From_stopM = true;

  /* Config code for STM32_WPAN (HSE Tuning must be done before system clock configuration) */
  MX_APPE_Config();

  ALGORTM.WakeUp_From_stopM = true;


  Load_Values_From_FLASH();

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

  /* Configure the peripherals common clocks */
  PeriphCommonClock_Config();

  /* IPCC initialisation */
  MX_IPCC_Init();

//  LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);





  MX_GPIO_Init();

  MX_RTC_Init();


  MX_I2C3_Init();
  MX_TIM1_Init();
  MX_TIM2_Init();
  MX_TIM17_Init();
//  MX_ADC1_Init();



  /* Configure RTC to use WUT */
   Configure_RTC();
   /* Note: On STM32WB, both CPU1 and CPU2 must be in standby mode to set the entire system in standby mode */
   if ((LL_PWR_IsActiveFlag_C1SB() != 0)
       && (LL_PWR_IsActiveFlag_C2SB() != 0)
      )
   {
     /* ##### Run after standby mode ##### */
     /* Clear Standby flag */
     LL_PWR_ClearFlag_C1STOP_C1STB();
     LL_PWR_ClearFlag_C2STOP_C2STB();

     /* Reset RTC Internal Wake up flag */
     LL_RTC_ClearFlag_WUT(RTC);

     /* Slow Toggle LED */
     //LED_Blinking(LED_BLINK_SLOW);
   }
   else
   {

     /* ##### Run after normal reset ##### */
     /* Fast Toggle LED in waiting for user-button press */
    // WaitForUserButtonPress();

     /* Enable wake-up timer and enter in standby mode */
   }





  ALGORTM.WakeUp_From_stopM = true;
  sleep_UUID_sameconn = false;



  HAL_GPIO_WritePin(Enable_DS_GPIO_Port,Enable_DS_Pin, GPIO_PIN_SET);


  HAL_GPIO_WritePin(EN_125_GPIO_Port, EN_125_Pin, GPIO_PIN_SET);
  HAL_GPIO_WritePin(PS_125_GPIO_Port,PS_125_Pin, GPIO_PIN_SET);



	SET_CONFIG_PAGE(CF_PAGE_1+TXDIS); 									//0x51
	HAL_Delay(37);
	SET_CONFIG_PAGE(CF_PAGE_1+TXDIS); 									//0x51
	HAL_Delay(41);
	trycount = 0;
	successcountuid = 0;
	successcountslct = 0;
	successchallengecnt = 0;
	successtagreadcnt = 0;
	i=7;
	for(i=0; i<64; i++)
	memset(&saverecord[i],0,4);
	i=0;
	UTTS_Routine(i);                                               //       init


  //-------------------------------------------------    Sensor ultra low power init -------------------------------//
  Ism330_Init_ULP();

	HAL_GPIO_TogglePin(LED5_GPIO_Port, LED5_Pin);

HAL_Delay(200);

		//Enable_Wakeup_Pins();

		//Enter_ULP();



	HAL_GPIO_WritePin(Enable_DS_GPIO_Port,Enable_DS_Pin, GPIO_PIN_SET);


  if (HAL_TIM_Base_Start_IT(&htim17) != HAL_OK)
  {
      Error_Handler();
  }

	 int result = 0;

for (int attempt = 0; attempt < 2; ++attempt)
{

	  HAL_Delay(150);
	 result = VerifyCertifica();

	if (result == 1) {

		HAL_GPIO_TogglePin(LED7_GPIO_Port, LED7_Pin);


		Flash_Erase_Pages(FLASH_ROM_BAT_ID_ADDRESS, 2);


		uint8_t ROM_BAT_ID[4];
		memcpy(ROM_BAT_ID, romID, sizeof(ROM_BAT_ID));
		uint32_t ROM_BAT_ID_flash;
		memcpy(&ROM_BAT_ID_flash, ROM_BAT_ID, sizeof(ROM_BAT_ID_flash));
		Flash_Write_Data(FLASH_ROM_BAT_ID_ADDRESS, &ROM_BAT_ID_flash, 1);
		ReadAndTransmitFromFlash(FLASH_ROM_BAT_ID_ADDRESS);

		break;
	}

}



  MX_ADC1_Init();
  HAL_Delay(10);
  battery_typ = batType();
  Device_info.bat_level =  Read_Battery_Level(battery_typ);

  if (HAL_TIM_Base_Stop_IT(&htim17) != HAL_OK)
  {
      Error_Handler();
  }



	HW_IPCC_Disable();
	LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);
	  Configure_RTC();

	  RTC_WakeUpTimer_Set_LL(0x2524);

	  Enable_Wakeup_Pins();

	  EnterStandbyMode();


  /* Application init */
  MX_APPE_Init();


	ALGORTM.TAG_Read_0 = true;
	ALGORTM.TTO_config = false;





  /* Main Loop  */
  while (1)
  {
}
void Configure_RTC(void)
{
  /*##-1- Enables the PWR Clock and Enables access to the backup domain #######*/
  /* To change the source clock of the RTC feature (LSE, LSI), you have to:
     - Enable the power clock
     - Enable write access to configure the RTC clock source (to be done once after reset).
     - Reset the Back up Domain
     - Configure the needed RTC clock source */

  LL_PWR_EnableBkUpAccess();

  /*##-2- Configure LSE/LSI as RTC clock source ###############################*/
#ifdef RTC_CLOCK_SOURCE_LSE
  /* Enable LSE only if disabled.*/
  if (LL_RCC_LSE_IsReady() == 0)
  {
    LL_RCC_ForceBackupDomainReset();
    LL_RCC_ReleaseBackupDomainReset();
    LL_RCC_LSE_Enable();
#if (USE_TIMEOUT == 1)
    Timeout = LSE_TIMEOUT_VALUE;
#endif /* USE_TIMEOUT */
    while (LL_RCC_LSE_IsReady() != 1)
    {
#if (USE_TIMEOUT == 1)
      if (LL_SYSTICK_IsActiveCounterFlag())
      {
        Timeout --;
      }
      if (Timeout == 0)
      {
        /* LSE activation error */
        LED_Blinking(LED_BLINK_ERROR);
      }
#endif /* USE_TIMEOUT */
    }
    LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE);

    /*##-3- Enable RTC peripheral Clocks #######################################*/
    /* Enable RTC Clock */
    LL_RCC_EnableRTC();
    LL_APB2_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB);
  }
#elif defined(RTC_CLOCK_SOURCE_LSI)
  if (LL_RCC_LSI1_IsReady() == 0)
  {
    LL_RCC_ForceBackupDomainReset();
    LL_RCC_ReleaseBackupDomainReset();
    LL_RCC_LSI1_Enable();
#if (USE_TIMEOUT == 1)
    Timeout = LSI_TIMEOUT_VALUE;
#endif /* USE_TIMEOUT */
    while (LL_RCC_LSI1_IsReady() != 1)
    {
#if (USE_TIMEOUT == 1)
      if (LL_SYSTICK_IsActiveCounterFlag())
      {
        Timeout --;
      }
      if (Timeout == 0)
      {
        /* LSI1 activation error */
        LED_Blinking(LED_BLINK_ERROR);
      }
#endif /* USE_TIMEOUT */
    }
    LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSI);

    /*##-3- Enable RTC peripheral Clocks #######################################*/
    /* Enable RTC Clock */
    LL_RCC_EnableRTC();
    LL_APB2_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB);
  }

#else
//#error "configure clock for RTC"
#endif

  /*##-4- Configure RTC ######################################################*/
  /* Disable RTC registers write protection */
  LL_RTC_DisableWriteProtection(RTC);

  /* Set prescaler according to source clock */
  LL_RTC_SetAsynchPrescaler(RTC, RTC_ASYNCH_PREDIV);
  LL_RTC_SetSynchPrescaler(RTC, RTC_SYNCH_PREDIV);

  /* Disable wake up timer to modify it */
  LL_RTC_WAKEUP_Disable(RTC);

  /* Wait until it is allow to modify wake up reload value */
#if (USE_TIMEOUT == 1)
  Timeout = RTC_TIMEOUT_VALUE;
#endif /* USE_TIMEOUT */

  while (LL_RTC_IsActiveFlag_WUTW(RTC) != 1)
  {
#if (USE_TIMEOUT == 1)
    if (LL_SYSTICK_IsActiveCounterFlag())
    {
      Timeout --;
    }
    if (Timeout == 0)
    {
      /* LSI activation error */
      LED_Blinking(LED_BLINK_ERROR);
    }
#endif /* USE_TIMEOUT */
  }

  /* Setting the Wakeup time to RTC_WUT_TIME s
       If LL_RTC_WAKEUPCLOCK_CKSPRE is selected, the frequency is 1Hz,
       this allows to get a wakeup time equal to RTC_WUT_TIME s
       if the counter is RTC_WUT_TIME */
  LL_RTC_WAKEUP_SetAutoReload(RTC, RTC_WUT_TIME);
  LL_RTC_WAKEUP_SetClock(RTC, LL_RTC_WAKEUPCLOCK_CKSPRE);

  /* Enable RTC registers write protection */
  LL_RTC_EnableWriteProtection(RTC);

}
/**
  * @brief  Function to configure and enter in STANDBY Mode.
  * @PAram  None
  * @retval None
  */
void EnterStandbyMode(void)
{
  /* ######## ENABLE WUT #################################################*/
  /* Disable RTC registers write protection */
  LL_RTC_DisableWriteProtection(RTC);

  /* Enable wake up counter and wake up interrupt */
  /* Note: Periodic wakeup interrupt should be enabled to exit the device
     from low-power modes.*/
  LL_RTC_EnableIT_WUT(RTC);
  LL_RTC_WAKEUP_Enable(RTC);

  /* Enable RTC registers write protection */
  LL_RTC_EnableWriteProtection(RTC);

  /* ######## ENTER IN STANDBY MODE ######################################*/
  /** Request to enter STANDBY mode
    * Following procedure describe in STM32WBxx Reference Manual
    * See PWR part, section Low-power modes, Standby mode
    */
  /* Reset Internal Wake up flag */
  LL_RTC_ClearFlag_WUT(RTC);

  /* Check that PWR Internal Wake-up is enabled */
  if (LL_PWR_IsEnabledInternWU() == 0)
  {
    /* Need to enable the Internal Wake-up line */
    LL_PWR_EnableInternWU();
  }

  /* Set Standby mode */
  LL_PWR_SetPowerMode(LL_PWR_MODE_STANDBY);

  /* Set Standby mode of CPU2 */
  /* Note: On STM32WB, both CPU1 and CPU2 must be in Standby mode to set the entire system in Standby mode */
  LL_C2_PWR_SetPowerMode(LL_PWR_MODE_STANDBY);

  /* Set SLEEPDEEP bit of Cortex System Control Register */
  LL_LPM_EnableDeepSleep();

  /* This option is used to ensure that store operations are completed */
#if defined ( __CC_ARM)
  __force_stores();
#endif

  /* Request Wait For Interrupt */
  __WFI();
}

void Enable_Wakeup_Pins(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // Wakeup pinleri için GPIO clock'larını aktif et
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();

    // 1. PA0 ve PC5 pinlerini default INPUT (pull yok) moduna al
    // PA0 = WakeUp1
    GPIO_InitStruct.Pin = GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    // PC5 = WakeUp5
    GPIO_InitStruct.Pin = GPIO_PIN_5;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    // 2. Backup domain erişimini aç (gerekiyorsa)
    LL_PWR_EnableBkUpAccess();

    // 3. Önce eski konfigürasyonları sıfırla
  //  LL_PWR_DisableWakeUpPin(LL_PWR_WAKEUP_PIN1);
    LL_PWR_DisableWakeUpPin(LL_PWR_WAKEUP_PIN5);
    LL_PWR_ClearFlag_WU();

    // 4. WakeUp Pin 1 ve 5'i aktif et (default rising edge ile)
 //   LL_PWR_EnableWakeUpPin(LL_PWR_WAKEUP_PIN1);  // PA0
    LL_PWR_EnableWakeUpPin(LL_PWR_WAKEUP_PIN5);  // PC5
}


void RTC_WakeUpTimer_Set_LL(uint32_t wakeup_counter)
{
    /* RTC write protection disable */
    LL_RTC_DisableWriteProtection(RTC);

    /* WakeUp timer disable before config */
    LL_RTC_WAKEUP_Disable(RTC);

    /* Wait for WUTWF flag (WakeUp Timer Write Flag) */
    while (!LL_RTC_IsActiveFlag_WUTW(RTC));

    /* Set wakeup auto-reload value */
    LL_RTC_WAKEUP_SetAutoReload(RTC, wakeup_counter);

    /* Set wakeup clock divider (RTC/16) */
    LL_RTC_WAKEUP_SetClock(RTC, LL_RTC_WAKEUPCLOCK_DIV_16);

    /* Clear WUTF flag */
    LL_RTC_ClearFlag_WUT(RTC);

    /* Enable wakeup interrupt */
    LL_RTC_EnableIT_WUT(RTC);

    /* Enable EXTI Line 22 for RTC WakeUp */
    LL_EXTI_EnableIT_0_31(LL_EXTI_LINE_22);
    LL_EXTI_EnableRisingTrig_0_31(LL_EXTI_LINE_22);

    /* Enable RTC WakeUp */
    LL_RTC_WAKEUP_Enable(RTC);

    /* RTC write protection enable */
    LL_RTC_EnableWriteProtection(RTC);

    /* Enable NVIC interrupt for RTC WakeUp */
    NVIC_SetPriority(RTC_WKUP_IRQn, 0);
    NVIC_EnableIRQ(RTC_WKUP_IRQn);
}
0 REPLIES 0