cancel
Showing results for 
Search instead for 
Did you mean: 

LPUART receive data broken in STOP mode with LSE

kein
Associate III

Hello everyone:

I'm working with board NUCLEO-U031R8, and need to wake up when LPUART receive data which using LSE with 32768Hz.

MCU would send back the receive data which end with '\n', and it works fine in running mode, and a special command 'S' let MCU go into stop mode and wait next data, and send back receive data when wakeup.

The receive data length is correct while wakeup in stop mode, but the receive data is broken, and if has next command it will reply as normal, the communication like this:

kein_2-1726454021135.png

 

And here is the sample code:

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

  /* Configure the system clock */
  SystemClock_Config();
  LL_RCC_LSE_EnablePropagation();
  while(LL_RCC_LSE_IsPropagationReady() != 1);

  /* Initialize all configured peripherals */
  MX_GPIO_Init();

  MX_LPUART1_UART_Init();
  LL_LPUART_EnableIT_RXNE_RXFNE(LPUART1);
  LL_LPUART_SetWKUPType(LPUART1, LL_LPUART_WAKEUP_ON_RXNE); // Set   LPUART1->CR3.WUS to wake-up on RXNE

  /* Infinite loop */
  LPUART_SendStr("Start\r\n");
  while (1)
  {
    if (rxFlag > 0) {
      if (rxBuf[0] == 'S') {    // check sleep command
        // reset the receive data
        rxFlag = 0;
        rxIdx = 0;
        LPUART_SendStr("Sleeping...\r\n");

        LL_LPUART_EnableInStopMode(LPUART1);                      // Set   LPUART1->CR1.UESM
        LL_PWR_EnableLowPowerRunMode();                           // Set   PWR->CR1.LPR
        LL_PWR_SetPowerMode(LL_PWR_MODE_STOP1);                   // Set   PWR->CR1.LPMS
        // ------------------ Sleep ------------------
        SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
        __WFI();
        CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
        // -------------------------------------------
        LL_PWR_DisableLowPowerRunMode();                          // Clear PWR->CR1.LPR
        LL_LPUART_DisableInStopMode(LPUART1);                     // Clear LPUART1->CR1.UESM

        LL_mDelay(200);                 // delay for receive data compeleted
        LPUART_Send(rxBuf, rxIdx);      // send back the receive data
      }
      else {
        // not Sleep command, send back the receive data
        LPUART_Send(rxBuf, rxFlag);
      }
      rxFlag = 0;
      rxIdx = 0;
    }
    LL_mDelay(100);
  }
}

void USART3_LPUART1_IRQHandler(void)
{
  if (LL_LPUART_IsActiveFlag_WKUP(LPUART1) && LL_LPUART_IsEnabledIT_WKUP(LPUART1)) {
    LL_LPUART_DisableIT_WKUP(LPUART1);
    LL_LPUART_ClearFlag_WKUP(LPUART1);
  }

  uint8_t ch = LL_LPUART_ReceiveData8(LPUART1);
  rxBuf[rxIdx++] = ch;
  if (ch == '\n') rxFlag = rxIdx;
}

 Anyone have any idea what's going on?

Regards.

1 REPLY 1
kein
Associate III

I found another solution is using HSI instead LSE, it makes everything goes fine, and current consumption is even lower than using an active LSE. So I decided to use HSI as the clock source for LPUART for now.

And I would like to clarify a few questions:

  • When environment temperature is very low or high, can I expect the tolerance of HSI to remain within 2%? I'm concerned that a significant deviation could lead to communication failures.
  • Just out of curiosity, why there is a LPUART receiving problem when using LSE? maybe just a hardware issue with LSE crystal or others?

Best Regards.