cancel
Showing results for 
Search instead for 
Did you mean: 

LPUART fail wakeup in STOP2

npatil15
Associate III

Hello,

Using Modbus master and slave communication, where Modbus master working fine, I have issue with slave device communication.

Using HAL_UARTEx_ReceiveToIdle_IT() for receiving modbus frame, and HAL_UART_Transmit_IT() to transmit response. Currently doing only read for testing purpose.

Issue: LPUART does not wakeup on receive interrupt.

Here is the information below

npatil15_0-1762921775853.pngnpatil15_1-1762921798795.png

During Init()

#define     LPUART1_EXTI_ENABLE_IT()   (EXTI->IMR1 |= EXTI_IMR1_IM28)

LPUART1_EXTI_ENABLE_IT();
__HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI);
 __HAL_RCC_HSI_ENABLE();

 

And here I will go to sleep mode if no rx/tx going on. So I will maintain the state busy until rx to tx process is complete. Once it complete, it will go to sleep mode. Here below is sleep mode logic

  //Preparation for next receive data 
   RS485_RX_ENABLE();//Its macro to receive RX data on line.
  __HAL_UART_FLUSH_DRREGISTER(&hlpuart1);
  HAL_UART_AbortReceive(&hlpuart1)
  HAL_UARTEx_ReceiveToIdle_IT(&hlpuart1, &gRxBuf[0], UART_RX_BUF_SIZE);

  //Below code is to go stop2 mode
  __HAL_UART_CLEAR_FLAG(&hlpuart1, UART_CLEAR_PEF | UART_CLEAR_NEF | UART_CLEAR_OREF);
  uint32_t dummy = hlpuart1.Instance->RDR; // flush RDR
  (void)dummy;  

   WakeUpSelection.WakeUpEvent = UART_WAKEUP_ON_STARTBIT;
  if (HAL_UARTEx_StopModeWakeUpSourceConfig(&hlpuart1, WakeUpSelection) != HAL_OK)
  {
    Error_Handler();
  }
  while (__HAL_UART_GET_FLAG(&hlpuart1, USART_ISR_BUSY) == SET);

  /* make sure that LPUART is ready to receive
   * (test carried out again later in HAL_UARTEx_StopModeWakeUpSourceConfig) */
  while (__HAL_UART_GET_FLAG(&hlpuart1, USART_ISR_REACK) == RESET);

  /* Enable the LPUART Wake UP from STOP mode Interrupt */
  __HAL_UART_DISABLE_IT(&hlpuart1, UART_IT_WUF);
  __HAL_UART_ENABLE_IT(&hlpuart1, UART_IT_WUF);

  /* enter STOP mode */
  HAL_UARTEx_EnableStopMode(&hlpuart1);
  HAL_SuspendTick();
  HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
  HAL_ResumeTick();
  Reset_SystemClock();
  HAL_UARTEx_DisableStopMode(&hlpuart1);
#define     LPUART1_EXTI_ENABLE_IT()   (EXTI->IMR1 |= EXTI_IMR1_IM28)

LPUART1_EXTI_ENABLE_IT();
static void MX_LPUART1_UART_Init(void)
{
  hlpuart1.Instance = LPUART1;
  hlpuart1.Init.BaudRate = 115200;
  hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;
  hlpuart1.Init.StopBits = UART_STOPBITS_1;
  hlpuart1.Init.Parity = UART_PARITY_NONE;
  hlpuart1.Init.Mode = UART_MODE_TX_RX;
  hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  hlpuart1.FifoMode = UART_FIFOMODE_ENABLE;
  if (HAL_UART_Init(&hlpuart1) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_RS485Ex_Init(&hlpuart1, UART_DE_POLARITY_HIGH, 0, 0) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&hlpuart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&hlpuart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_EnableFifoMode(&hlpuart1) != HAL_OK)
  {
    Error_Handler();
  }

  /* USER CODE BEGIN LPUART1_Init 2 */
  LPUART1_EXTI_ENABLE_IT();
  /* USER CODE END LPUART1_Init 2 */
}

For testing I have tried lptimer to wakeup and it work, but it doesnt wakeup at rx interrupt.

Please help me to identify the issue.

Thanks,

Nitin

8 REPLIES 8
Saket_Om
ST Employee

Hello @npatil15 

Please specify the clock source after wakeup as implemented in the example UART_WakeUpFromStopUsingFIFO

   __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI);

 

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.
Saket_Om
npatil15
Associate III

Hello @Saket_Om ,

I have already used that clock source also mentioned in the code description, that didnt help.

I found that, I have implemented silence time logic to detect frame end, using HAL_GetTicks(), but looks like that is not working correctly or not waking up the hal ticks correctly after wakeup from stop2 mode

So I was doing like this, and that does not wakeup the hal tick correctly makes it to block forever silence time logic as it doesnt timeout at all.

 HAL_SuspendTick();
 HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
 HAL_ResumeTick();
 Reset_SystemClock();

So just commented Suspend and ResumeTick() function works. 

Below logic also work, but need to add delay of 1 ms, as its not correct way.

 HAL_SuspendTick();
 HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
 HAL_ResumeTick();
 HAL_Delay(1);
 Reset_SystemClock();

 Note: In Reset_SystemClock(); I was just calling same function of SystemClock_Config() which was generated by STM32CubeMx.

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();
  }
}

So, I just need correct way for waiting this hal ticks to wakeup correctly, instead of adding this delay.

Thanks,

Nitin

Hello @npatil15 

Did you check with the config below?

WakeUpSelection.WakeUpEvent = UART_WAKEUP_ON_READDATA_NONEMPTY;

 

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.
Saket_Om
npatil15
Associate III

Hello,

This doesnt work for me, even using UART_WAKEUP_ON_READDATA_NONEMPTY or UART_WAKEUP_ON_STARTBIT. If I tried and it doesnt wakeup, instead it doesnt wakeup at all.

Thanks,

Nitin

Hello @npatil15 

Could you please provide a minimal example (With ioc file) so that we can reproduce the issue on our end?

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.
Saket_Om
npatil15
Associate III

Hello,

Looks like the issue is not with UART wakeup, the issue is with HAL_GetTicks() which is not incrementing the ticks and stuck forever in silence time logic which I wait for 3ms as sign of completion of frame. 

So, the issue is with HAL_GetTicks() does not wakeup correctly at UART interrupt wakeup. 

Thanks,

Nitin

Hello @npatil15 

Did the HAL_GetTicks() work correctly before entering to 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.
Saket_Om
npatil15
Associate III

Hello,

This doesn't solve my problem, But I have done some workaround to wait for systicks to wake up and then go ahead.

 HAL_SuspendTick();
 HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
 HAL_ResumeTick();
 //HAL_Delay(1);
 uint32_t t0 = HAL_GetTicks();
 while(t0 == HAL_GetTicks());
 Reset_SystemClock();

So, this solves the problem, but again it looks like workaround.

Thanks,

Nitin