cancel
Showing results for 
Search instead for 
Did you mean: 

PA0 WakeUp from Deep stop unreliable on STM32WL31

sbelcatronic
Associate III

Good day.

 

I am using STM32WL31 on a custom board.

DeepStop mode entry works correctly, but wakeup from PA0 (WakeUp pin) is not reliable or does not work. I used the example code in project:

STM32Cube_FW_WL3_V1.3.1\Projects\NUCLEO-WL33CC\Examples\PWR\PWR_DEEPSTOP

The same code I use in my custom board works correctly on NUCLEO-WL33CC2 board (I have tested succefull the code on the NUCLEO-WL33CC2). In my opinion the difference from my custom bord + my code and the NUCLEO-WL33CC2 is the microcontroller; the NUCLEO-WL33CC2 mount the STM32WL33, my board mount the STM32WL31.

 

Code sequence foe enter in deep stop:

1. Enable wakeup pin (PA0, PA11 used as wakeup pins are connected by a button to GND). Internal pull-up enabled using LL_PWR_EnableGPIOPullUp on PA0 e PA11

2. Clear WUF flags

3. Enter DeepStop

 

When I press PA0 or PA11 buttons the MCU does not resume execution OR behaves inconsistently, it look like as the micro is in an undefined state.

After programmed the micro it seam to enter in deep stop and when I press the wakeup pin it exit from deep stop, execute the main and go back in deep stop. If I wakeup again by the IO pin it not exit from deep stop but look like in an udefined state.

 

In this conversation:

https://community.st.com/t5/stm32-mcus-wireless/stm32wl31-fails-to-exit-deepstop-from-rtc-wakeup/m-p/887400#M27790

The user marvdm report a similar behaver on the same MCU (STM32WL31)

 

This is my main.c:

int main(void)
{

  /* USER CODE BEGIN 1 */

  /* 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();

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

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
//  MX_GPIO_Init();
//  MX_TIM2_Init();
//  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

  GPIO_InitTypeDef GPIO_InitStruct = {0};
//
//  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
//
//  /*Configure GPIO pins : OUT_FREQUENCE_SELECT_Pin RE_485_Pin DE_485_Pin DL3_Pin
//                           DEBUG_1_Pin DL2_Pin */
  GPIO_InitStruct.Pin = DL3_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  LL_PWR_EnableGPIOPullUp( LL_PWR_GPIO_B, DL3_Pin);
  //LL_PWR_EnableGPIOPullUp( LL_PWR_GPIO_A, GPIO_PIN_0);


  /* Check if the system was resumed from Deepstop mode */
    if (__HAL_PWR_GET_FLAG(PWR_FLAG_DEEPSTOPF) != RESET)
    {
      /* Clear Deepstop flag */
      __HAL_PWR_CLEAR_FLAG(PWR_FLAG_DEEPSTOPF);

      /* Check and Clear the Wakeup flag */
//      if (__HAL_PWR_GET_FLAG(PWR_FLAG_WUFB0) != RESET)
//      {
//        __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUFB0);
//      }
      /* Check and Clear the Wakeup flag */
	  if (__HAL_PWR_GET_FLAG(PWR_FLAG_WUFA0) != RESET)
	  {
		__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUFA0);
	  }

      //HAL_GPIO_WritePin(DL2_GPIO_Port, DL2_Pin, GPIO_PIN_SET);
	  HAL_GPIO_WritePin(DL3_GPIO_Port, DL3_Pin, GPIO_PIN_SET);
      HAL_Delay(3000);
      HAL_GPIO_WritePin(DL3_GPIO_Port, DL3_Pin, GPIO_PIN_RESET);
      /* Wait that user release the USER push-button */
      //NVIC_SystemReset();
    }


    for (uint16_t i=0; i<10; i++)
    {	//Lampeggi il led
    	HAL_GPIO_WritePin(DL3_GPIO_Port, DL3_Pin, GPIO_PIN_SET);
    	HAL_Delay(250);
    	HAL_GPIO_WritePin(DL3_GPIO_Port, DL3_Pin, GPIO_PIN_RESET);
    	HAL_Delay(250);
    }

    HAL_GPIO_WritePin(DL3_GPIO_Port, DL3_Pin, GPIO_PIN_RESET);

    //HAL_GPIO_WritePin(DL2_GPIO_Port, DL2_Pin, GPIO_PIN_SET);
    LL_PWR_EnableGPIOPullUp( LL_PWR_GPIO_A, PWR_WAKEUP_PIN0);	//LL_PWR_DisableGPIOPullUp( LL_PWR_GPIO_A, PWR_WAKEUP_PIN0);
    LL_PWR_EnableGPIOPullUp( LL_PWR_GPIO_B, PWR_WAKEUP_PIN10);	//LL_PWR_DisableGPIOPullUp(LL_PWR_GPIO_B, PWR_WAKEUP_PIN10); //
	/* Enable WakeUp Pin PWR_WAKEUP_PIN0 connected to  */
	HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PORTA, PWR_WAKEUP_PIN0, PWR_WUP_FALLEDG );
	HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PORTB, PWR_WAKEUP_PIN10, PWR_WUP_FALLEDG );	//PB10 = B_APRI_Pin
	/* Clear all related wakeup flags*/
	//__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF_ALL); // Pulisce tutti i flag di Wakeup
	//__HAL_PWR_CLEAR_FLAG(PWR_FLAG_DEEPSTOPF);
    //__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF_ALL);
    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUFA0);
    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUFB10);

    //MODIFY_REG_FIELD(PWR->DBGR, PWR_DBGR_DEEPSTOP2, 1);

	//sConfigDEEPSTOP.deepStopMode = PWR_DEEPSTOP_WITH_SLOW_CLOCK_ON;
	sConfigDEEPSTOP.deepStopMode = PWR_DEEPSTOP_WITH_SLOW_CLOCK_OFF;
	/* Enter the Deepstop mode */
	 HAL_PWR_ConfigDEEPSTOP(&sConfigDEEPSTOP);
	 HAL_PWR_EnterDEEPSTOPMode();

	 while (1)
	 {
		HAL_GPIO_WritePin(DL3_GPIO_Port, DL3_Pin, GPIO_PIN_SET);
		HAL_Delay(1000);
		HAL_GPIO_WritePin(DL3_GPIO_Port, DL3_Pin, GPIO_PIN_RESET);
		HAL_Delay(1000);
	 }


  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
//	}
  /* USER CODE END 3 */
}

 

Question:

Is there any known limitation or required sequence for STM32WL31 DeepStop wakeup from GPIO?

Are there differences vs STM32WL33?

1 ACCEPTED SOLUTION

Accepted Solutions

I experienced the same issue. It was caused by using my own linker script, which corrupted the AppBase variable.

The AppBase variable is described on page 50 of the RM0511 Reference Manual.

View solution in original post

10 REPLIES 10
Imen.D
ST Employee

Hello @sbelcatronic ,

Make sure that all configuration steps and conditions mentioned in the Datasheet (page 14 - section: 3.6.2 Deepstop mode) are followed:

  • The radio (MR_SUBG) and CPU are sleeping (WFI with SLEEPDEEP bit set).
  • No unmasked wake-up sources are active (PWRC_CR1.LPMS = 0).
  • The system is clocked on RC64MPLL (HSI or PLL locked mode).
  • ...
  • WL31.png
When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
sbelcatronic
Associate III

Thank you Imen.d 

I checked all the points.

1-' the radio (MR_SUBGHz) is sleeping' :  I do not configure the MR_SUBGHz, so it is in sleep.

2-' The CPU is sleeping (WFI with SLEEPDEEP bit activated)' : I call the function HAL_PWR_EnterDEEPSTOPMode(); so it set proply the bits.

3-' No unmasked wake-up sources are active (including those from a previous wakeup sequence for which the software did not clear the associated flag after wakeup) the PWRC_CR1.LPMS bit is equal to 0': again I call the function HAL_PWR_EnterDEEPSTOPMode() and this do the calls:

  /* Clear all the wake-up pin flags */
  LL_PWR_ClearInternalWakeupSource(LL_PWR_WAKEUP_ALL);
  LL_PWR_ClearWakeupSource(PWR_WAKEUP_PORTA, LL_PWR_WAKEUP_ALL);
  LL_PWR_ClearWakeupSource(PWR_WAKEUP_PORTB, LL_PWR_WAKEUP_ALL);

 

4-'The system is clocked on RC64MPLL (HSI or PLL locked mode)' : My SystemClock_Config() is

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

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure the SYSCLKSource and SYSCLKDivider
  */
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.SYSCLKDivider = RCC_RC64MPLL_DIV1;

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

 I use HSI clock source as required.

5-' Reset PWRC_CR5.GPIORET bit when PWRC_DBGR.DEEPSTOP2 bit is set, otherwise set PWRC_CR5.GPIORET bit':

the flag PWRC_CR5.GPIORET do not exist (I guess is a datasheet error) but I set the bit  PWRC_CR2.GPIORET by adding the function call HAL_PWREx_EnableGPIORetention(); before enter deep stop.

 

I think I have respected all the requirement in 3.6.2, but the problem still.

 

Thank 

I forgot the last point:

5-' If SMPS clock variable rate multiplier is enabled RCC_KRMR.KRMEN=1 (see SMPS clock variable rate multiplier register (RCC_KRMR)), in order to guarantee a good SMPS startup at next wakeup, its mandatory to put RCC_CFGR.SMPSDIV=0 ':

I verified by the debugger the flag RCC_KRMR.KRMEN=0 so the clear the flag RCC_CFGR.SMPSDIV=0 is not mandatory.

 

sbelcatronic

sbelcatronic
Associate III

 

when the cpu wakeup, maybe the CPU enter in internal serial boot loader? I read in the datasheet:

 

The bootloader is activated by hardware by forcing PA10 high during hardware reset, otherwise, application residing in flash memory is launched

 

I installed a pull down resistor in PA10 pin, but this not resolve my problem.

 

In the reference manual rm0511 is written:

 

ST provides a boot loader executed after each CPU reboot. This boot loader has its own documentation.

STM32WL30xx/31xx/33xx devices latch the PA8 / PA9 / PA10 / PA11 / PB12 / PB13 / PB14/ PB15 pads value at POR. The information is available in PWRC_SR2 register (see Statusregister 2 (PWRC_SR2)). One of those eight I/Os can be used by the boot loader as bootindication between a normal boot or a boot on serial interface.

 

PA10 pin is the only pin used for enter in boot mode or are used for this even the pin PA8 / PA9 / PA10 / PA11 / PB12 / PB13 / PB14/ PB15 ?

 

 

Simone

Hi @sbelcatronic ,

Only the PA10 is used for entering in boot mode.

The bootloader is activated by hardware when PA10 is set high during a hardware reset. Otherwise, the application in flash memory launches. 

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
sbelcatronic
Associate III

Thank you Imen

for safety I added an external pull down resistor on PA10 so I'm sure it does not enter in bootloader on wakeup, but this not resolve my problem. The STM32WL31 still in undefined state on wakeup.

I have activated the debugger by the instruction:

HAL_PWREx_EnableDEEPSTOP2();	//equivale a MODIFY_REG_FIELD(PWR->DBGR, PWR_DBGR_DEEPSTOP2, 1);

When the micro wakeup and enter in the undefined state I receve this message from the debugger:

 

Break at address "0x100004ee" with no debug information available, or outside of program code.

 

The addrss 0x100004ee is in reseved area. What mean this message?

Thanks

Simone

Hi @sbelcatronic 

Can you please update and use the latest release of STM32CubeWL MCU package version 1.5.0 which contains enhancement and bug fixes. I hope this is helpful.

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
sbelcatronic
Associate III

Thank you Imen,

I update to the Firmware Package STM32Cube FW_WL3 V1.4.0, but still not working. I have the same problem, at wakeup the micro enter in undefined state.

Simone.

 

I experienced the same issue. It was caused by using my own linker script, which corrupted the AppBase variable.

The AppBase variable is described on page 50 of the RM0511 Reference Manual.