cancel
Showing results for 
Search instead for 
Did you mean: 

LPTIMER fail to wakeup in STOP2 mode for longer timeout

npatil15
Associate II

Hello,

Trying to achieve wakeup system at every 60 sec or more using LPTIMER1 in STOP2 mode.

Observation:

1. STOP2 = enable and LPTIMER = 60 sec --> Wakeup not work

2. STOP2 = disable and LPTIMER = 60 sec --> Wakeup work

3. STOP2 = enable and LPTIMER = 2 sec --> Wakeup work

4. STOP2 = disable and LPTIMER = 2 sec --> Wakeup work

 

void enterLowPowerMode()
{
  HAL_UARTEx_EnableStopMode(&hlpuart1);
  HAL_SuspendTick();
  HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
  HAL_ResumeTick();
  Reset_SystemClock();
  HAL_UARTEx_DisableStopMode(&hlpuart1);
}

Using LPTIMER1, below is the configuration, 

static void MX_LPTIM1_Init(void)
{

  /* USER CODE BEGIN LPTIM1_Init 0 */

  /* USER CODE END LPTIM1_Init 0 */

  LPTIM_OC_ConfigTypeDef sConfig1 = {0};

  /* USER CODE BEGIN LPTIM1_Init 1 */

  /* USER CODE END LPTIM1_Init 1 */
  hlptim1.Instance = LPTIM1;
  hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
  hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV64;
  hlptim1.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
  hlptim1.Init.Period = 31000;
  hlptim1.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
  hlptim1.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;
  hlptim1.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;
  hlptim1.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;
  hlptim1.Init.RepetitionCounter = 0;
  if (HAL_LPTIM_Init(&hlptim1) != HAL_OK)
  {
    Error_Handler();
  }
  sConfig1.Pulse = 30720;
  sConfig1.OCPolarity = LPTIM_OCPOLARITY_HIGH;
  if (HAL_LPTIM_OC_ConfigChannel(&hlptim1, &sConfig1, LPTIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN LPTIM1_Init 2 */
  HAL_LPTIM_IC_Start_IT(&hlptim1, LPTIM_CHANNEL_1);
  /* USER CODE END LPTIM1_Init 2 */
}

Help me what I'm missing here,

1 ACCEPTED SOLUTION

Accepted Solutions
npatil15
Associate II

Hello,

I found the solution,

I need to write this statement just after STOP2 mode to re-enable the wakeup, where I have done this in the ADC handler where it has to re-register but not sure why it was not registering their, it may be the issue with ADC somewhere, which was not worked during wakeup.

So, I have written this statement just after STOP2 wakeup and now it works fine.

HAL_LPTIM_IC_Start_IT(&hlptim1, LPTIM_CHANNEL_1);

 Thanks everyone for your kind support.

View solution in original post

9 REPLIES 9
Sarra.S
ST Employee

Hello @npatil15

First check if this limitation is applicable in your case: Device may remain stuck in LPTIM interrupt when entering Stop mode

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

npatil15
Associate II

Hello @Sarra.S 

 

Thanks for reply, this limitation does not applicable in my case.

I have gone through this section, and accordingly I'm not disabling LPTIMER in between of any process, actually it is by default enable during init.

npatil15_1-1747646592374.png

 

As per LPTIMER application if it is enabling all the time then it has to generate interrupt to wake up from stop2 mode. Let me know if I misunderstood the content.

Thanks,

Nitin

 

Sarra.S
ST Employee

Hello again, 

I have jus noticed that the LPTIMER1 is using the APB clock source with a low-power oscillator:

hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC

The APB clock is not available in STOP2 mode, so consider using an internal low-power oscillator (LSE or LSI)

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

npatil15
Associate II

Hello @Sarra.S 

Thanks to highlight, 

Here, I'm little confuse, as you see in the clock configuration I have set by default LSI clock to LPTIMER1, so I thought it was using LSI clock, but as you said it is not using it.

npatil15_0-1747713505196.png

And here is the clock autogenerated code for reference,

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

  /** Configure the main internal regulator output voltage
  */
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

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

 

As per my logic, at every wakeup on interrupt I reconfigure the clock (i.e, re-call SystemClock_Config() to retain its clock again, this is done because I want to run ADC calculation on wakeup so needs HSI clock to use. That is the case in clock configuration I have set LSI default clock to LPTIMER1, so that it will not affect its timing calculation due to wake up.)

Can you check what was wrong in the clock configuration and why it is not setting LSI clock to LPTIMER1?

Thanks,

Nitin

Hello again Nitin 

Could you modify the code to change the LPTIM clock source to use the LSI or another low-power oscillator and then test if the issue persists?

hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_LSI;

 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

npatil15
Associate II

Hello @Sarra.S 

I have checked the option (LPTIM_CLOCKSOURCE_LSI), but it is not available in my code.

Instead, I can see these options below, of which I have tried, LPTIM_CLOCKSOURCE_ULPTIM, but it is also not working.

/** @defgroup LPTIM_Clock_Source LPTIM Clock Source
  * @{
  */
#define LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC        0x00000000U
#define LPTIM_CLOCKSOURCE_ULPTIM                LPTIM_CFGR_CKSEL

 

Let me know if any more details needed.

Thansk,

Nitin

Hello,

you can try to set LSI as clock source for LPTIM1 by direct write to register. For this purpose there is register: Peripherals independent clock configuration register (RCC_CCIPR) (reference manual, page 202, STM32U0 series advanced Arm<Sup>®</Sup>-based 32-bit MCUs - Reference manual)

and LSI as clock source for LPTIM1 should be set by:

MODIFY_REG(RCC->CCIPR, RCC_CCIPR_LPTIM1SEL_Msk, RCC_CCIPR_LPTIM1SEL_0);

 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

npatil15
Associate II

Hello @Hl_st ,

I have tried with your solution but didnt worked,

Tried with

MODIFY_REG(RCC->CCIPR, RCC_CCIPR_LPTIM1SEL_Msk, RCC_CCIPR_LPTIM1SEL_0);

or

__HAL_RCC_LPTIM1_CONFIG(RCC_LPTIM1CLKSOURCE_LSI);

 

Just to mentioned I'm have tried at every possible location, also tried to use it after stop2 wakeup statement, but it didn't work. To see it is working I have enabled toggle LED just after wakeup and it is not blinking.

static void MX_LPTIM1_Init(void)
{

  /* USER CODE BEGIN LPTIM1_Init 0 */

  /* USER CODE END LPTIM1_Init 0 */

  LPTIM_OC_ConfigTypeDef sConfig1 = {0};

  /* USER CODE BEGIN LPTIM1_Init 1 */

  /* USER CODE END LPTIM1_Init 1 */
  hlptim1.Instance = LPTIM1;
  hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
  hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV2;
  hlptim1.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
  hlptim1.Init.Period = 63999;
  hlptim1.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
  hlptim1.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;
  hlptim1.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;
  hlptim1.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;
  hlptim1.Init.RepetitionCounter = 0;
  //__HAL_RCC_LPTIM1_CONFIG(RCC_LPTIM1CLKSOURCE_LSI);
  //MODIFY_REG(RCC->CCIPR, RCC_CCIPR_LPTIM1SEL_Msk, RCC_CCIPR_LPTIM1SEL_0);
  if (HAL_LPTIM_Init(&hlptim1) != HAL_OK)
  {
    Error_Handler();
  }
  //__HAL_RCC_LPTIM1_CONFIG(RCC_LPTIM1CLKSOURCE_LSI);
  //MODIFY_REG(RCC->CCIPR, RCC_CCIPR_LPTIM1SEL_Msk, RCC_CCIPR_LPTIM1SEL_0);
  sConfig1.Pulse = 63999;
  sConfig1.OCPolarity = LPTIM_OCPOLARITY_HIGH;
  if (HAL_LPTIM_OC_ConfigChannel(&hlptim1, &sConfig1, LPTIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN LPTIM1_Init 2 */
  //__HAL_RCC_LPTIM1_CONFIG(RCC_LPTIM1CLKSOURCE_LSI);
  //MODIFY_REG(RCC->CCIPR, RCC_CCIPR_LPTIM1SEL_Msk, RCC_CCIPR_LPTIM1SEL_0);
  HAL_LPTIM_IC_Start_IT(&hlptim1, LPTIM_CHANNEL_1);
  /* USER CODE END LPTIM1_Init 2 */
}

When I use below, with existing clock setting or as per your suggestions, 

hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV2/4/8/16; then it doesnt work.

hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV1;, it works always

 

Let me know if the statement is not at the correct position.

Thanks,

Nitin

 

npatil15
Associate II

Hello,

I found the solution,

I need to write this statement just after STOP2 mode to re-enable the wakeup, where I have done this in the ADC handler where it has to re-register but not sure why it was not registering their, it may be the issue with ADC somewhere, which was not worked during wakeup.

So, I have written this statement just after STOP2 wakeup and now it works fine.

HAL_LPTIM_IC_Start_IT(&hlptim1, LPTIM_CHANNEL_1);

 Thanks everyone for your kind support.