Flying Swissman
Flying Swissman

Reputation: 803

Entering Low Power Mode on STM32L0 to use USART1

I want to use as little power as possible reading USART1 at 300 baud approx. 40 bytes. There are numerous other peripherals but they don't need to run- all that needs to be running is the RTC in parallel. Peripherals need to be frozen, ram needs to be the same.

The way I see it Low power run mode is the optimal mode (please correct me if I'm wrong here) for this:

void HAL_PWREx_EnableLowPowerRunMode(void)
{
  /* Enters the Low Power Run mode */
  SET_BIT(PWR->CR, PWR_CR_LPSDSR);
  SET_BIT(PWR->CR, PWR_CR_LPRUN);
}

enter image description here

Now the clock configuration at the moment is

How do I go into this mode and recover from it?

// Init?
HAL_PWREx_EnableLowPowerRunMode();
HAL_PWREx_DisableLowPowerRunMode();
// Deinit?

My attempt at init, what am I missing here?

void init_clock(){


  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_PeriphCLKInitTypeDef PeriphClkInit;

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

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
    /**Configure the main internal regulator output voltage 
    */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);

    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_MSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_DIV4;
  RCC_OscInitStruct.HSICalibrationValue = 16;
  RCC_OscInitStruct.MSIState = RCC_MSI_ON;
  RCC_OscInitStruct.MSICalibrationValue = 0;
  RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_0;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
  PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_SYSCLK;

  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }

}

Upvotes: 3

Views: 3480

Answers (1)

Flying Swissman
Flying Swissman

Reputation: 803

The USART1 can receive a byte in stop mode and is also able to wake up.

The procedure to achieve low power is to use LSE for USART1 and wake up from stop mode on RXNE.

  UART_WakeUpTypeDef wakeup;
  wakeup.WakeUpEvent=UART_WAKEUP_ON_READDATA_NONEMPTY;
  HAL_UARTEx_StopModeWakeUpSourceConfig(&huart1,wakeup);   
  HAL_UARTEx_EnableStopMode(&huart1);

This is simpler and equal to if not better than BAM with DMA and Low Power Sleep.

Upvotes: 0

Related Questions