prattom
prattom

Reputation: 1743

Uart doesn't work after waking up from stop mode in stm32f4

I am using STOP mode to save power and also deinitialize GPIO to achieve maximum power saving. In this case current consumption goes below 1mA. I am using UART Rx pin as external interrupt to wake up board from STOP mode. The board does wake up but UART or other peripheral like DCMI doesn't work. Following is my code.

void MX_GPIO_Deinit()
{
    GPIO_InitTypeDef GPIO_InitStruct;
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOH_CLK_ENABLE();
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Pin = GPIO_PIN_All;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
    /* Disable GPIOs clock */
    __HAL_RCC_GPIOA_CLK_DISABLE();
    __HAL_RCC_GPIOB_CLK_DISABLE();
    __HAL_RCC_GPIOC_CLK_DISABLE();
    __HAL_RCC_GPIOH_CLK_DISABLE();
}

void stopMode(void)
{
  HAL_SuspendTick();
  MX_GPIO_Deinit();
  __HAL_RCC_PWR_CLK_ENABLE();
  HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);

  GPIO_InitTypeDef GPIO_InitStruct;
  __HAL_RCC_GPIOA_CLK_ENABLE();
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF8_UART4;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
}

void resumeStopMode(void)
{
    SystemClock_Config();
    HAL_ResumeTick();
    MX_GPIO_Init();

    HAL_UART_MspInit(&huart4);
    HAL_I2C_MspInit(&hi2c2);
    HAL_DCMI_MspInit(&hdma_dcmi);
    HAL_TIM_MspPostInit(&htim1);
    MX_DMA_Init();
    MX_UART4_Init();
    MX_I2C2_Init();
    MX_DCMI_Init();
    MX_TIM1_Init();

    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
}

int getChar()
{
   uint8_t InputData = 0;
   TimmingDelay = 50000;
   while (TimmingDelay !=0)
   {
       if (__HAL_UART_GET_FLAG(&huart4, UART_FLAG_ORE))
           __HAL_UART_CLEAR_OREFLAG(&huart4);

       if (__HAL_UART_GET_FLAG(&huart4, UART_FLAG_RXNE))
       {
           InputData = huart4.Instance->DR & 0x1FF;
           return InputData;
       }
   }
   return -1;
}

void main(void)
{
    stopMode()
    resumeStopMode() /* woken up by uart interrupt*/
    int receivedByte = 0;
    receivedByte = getChar() /* This line doesn't work after waking it goes into stop mode */
}

Since I deinitialize all GPIO I am not able to to debug. How can I make UART work properly after waking up from STOP mode.

Upvotes: 1

Views: 3383

Answers (3)

Brad Grissom
Brad Grissom

Reputation: 3943

I ran into almost this exact same issue and here was my solution (keep in mind I'm using UART2):

    HAL_UART_MspInit(&huart2);
    MX_USART2_UART_Init();

The reason that just calling the normal MX_USART2_UART_Init() function doesn't work is because the UART peripheral has state and wont re-initialize clocks if its state doesn't think it needs to:

    Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c

    308 HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
    309 {
    .
    .
    .
    327   if (huart->gState == HAL_UART_STATE_RESET)
    328   {
    .
    .
    .
    343     /* Init the low level hardware : GPIO, CLOCK */
    344     HAL_UART_MspInit(huart);

Upvotes: 0

storm
storm

Reputation: 11

This is my solution.

          HAL_UART_MspInit(&huart4);
          __HAL_UART_DISABLE(&huart4);
          __HAL_UART_ENABLE(&huart4);

but following do not work.

          HAL_UART_Init(&huart4);

Upvotes: 0

b7031719
b7031719

Reputation: 120

There is a wake-up latency associated with STOP mode to allow the HSI RC oscillator to wake up and potentially flash and the internal regulator. If the first byte is corrupt then it is most likely that it is a result of this latency.

Upvotes: 0

Related Questions