cancel
Showing results for 
Search instead for 
Did you mean: 

why HAL_UART_Transmit not working at clocks above 2 MHz?

alianvari
Associate III

I am using stm32l496, when in stm32cube I set the MSI clock above 2 MHz even if I don't change the Uart clock, when micro exits from lprun mode, HAL_UART_Transmit function not working or prints at a very delayed time for example if it must printed every 20 seconds, it does every 2 minutes, but if i don't use micro in low power mode and always be the run mode, prints correctly.

please help me.

best regards.

sprintf(AA_str,"ReadCounter= %d\r\n",EnLpTick);

HAL_UART_Transmit(&huart1,(uint8_t *)AA_str,strlen(AA_str),100);

HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)

{

 uint8_t *pdata8bits;

 uint16_t *pdata16bits;

 uint32_t tickstart;

 /* Check that a Tx process is not already ongoing */

 if (huart->gState == HAL_UART_STATE_READY)

 {

  if ((pData == NULL) || (Size == 0U))

  {

   return HAL_ERROR;

  }

  __HAL_LOCK(huart);

  huart->ErrorCode = HAL_UART_ERROR_NONE;

  huart->gState = HAL_UART_STATE_BUSY_TX;

  /* Init tickstart for timeout managment*/

  tickstart = HAL_GetTick();

  huart->TxXferSize = Size;

  huart->TxXferCount = Size;

  /* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */

  if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))

  {

   pdata8bits = NULL;

   pdata16bits = (uint16_t *) pData;

  }

  else

  {

   pdata8bits = pData;

   pdata16bits = NULL;

  }

  while (huart->TxXferCount > 0U)

  {

   if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)

   {

    return HAL_TIMEOUT;

   }

   if (pdata8bits == NULL)

   {

    huart->Instance->TDR = (uint16_t)(*pdata16bits & 0x01FFU);

    pdata16bits++;

   }

   else

   {

    huart->Instance->TDR = (uint8_t)(*pdata8bits & 0xFFU);

    pdata8bits++;

   }

   huart->TxXferCount--;

  }

  if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)

  {

   return HAL_TIMEOUT;

  }

  /* At end of Tx process, restore huart->gState to Ready */

  huart->gState = HAL_UART_STATE_READY;

  __HAL_UNLOCK(huart);

  return HAL_OK;

 }

 else

 {

  return HAL_BUSY;

 }

}

void SystemClock_Config(void)

{

 RCC_OscInitTypeDef RCC_OscInitStruct = {0};

 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

 /** Initializes the CPU, AHB and APB busses clocks 

 */

 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;

 RCC_OscInitStruct.MSIState = RCC_MSI_ON;

 RCC_OscInitStruct.MSICalibrationValue = 0;

 RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_7;

 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;

 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

 {

  Error_Handler();

 }

 /** 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_DIV4;

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

 }

 PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_LPTIM1;

 PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;

 PeriphClkInit.Lptim1ClockSelection = RCC_LPTIM1CLKSOURCE_PCLK;

 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)

 {

  Error_Handler();

 }

 /** Configure the main internal regulator output voltage 

 */

 if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)

 {

  Error_Handler();

 }

}

4 REPLIES 4
Danish1
Lead II

Entering LPRun mode forces the system clock frequency to be 2 MHz (or less).

So if you normally run faster than 2 MHz, you need to explicitly re-select that higher frequency after you've left LPRun.

This might be as simple as calling SystemClock_Config() again at that point.

Hope this helps,

Danish

I did these works, when entering LPRun mode calling SystemClock_Decrease() and after left LPRun calling SystemClock_Config(), but there is still the same problem.

void AA_EnableLPRun(void)

{

HAL_GPIO_WritePin(Temp_PWR_GPIO_Port,Temp_PWR_Pin,GPIO_PIN_SET);//power off Temp PWR

HAL_SPI_MspDeInit(&hspi1);

HAL_GPIO_DeInit(TempAD_CS_GPIO_Port, TempAD_CS_Pin);

SystemClock_Decrease();   

HAL_SuspendTick();

HAL_PWREx_EnableLowPowerRunMode();

}

void AA_WakeUp(void)

{

HAL_PWREx_DisableLowPowerRunMode();

SystemClock_Config();

HAL_Init();

SystemPower_Config();

HAL_ResumeTick();

MX_GPIO_Init();

huart1.gState = HAL_UART_STATE_RESET;

MX_USART1_UART_Init();

}

void SystemClock_Decrease(void)

{

 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 RCC_OscInitTypeDef RCC_OscInitStruct = {0};

 /* MSI is enabled after System reset, activate PLL with MSI as source */

 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;

 RCC_OscInitStruct.HSEState = RCC_HSE_OFF;

 RCC_OscInitStruct.HSIState = RCC_HSI_ON;

  RCC_OscInitStruct.MSIState = RCC_MSI_ON;

 RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_0;

 RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;

 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;

 if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

 {

  /* Initialization Error */

  Error_Handler();

 }

  

 /* Select MSI as system clock source and configure the HCLK, PCLK1 and PCLK2 

   clocks dividers */

 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;

 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)

 {

  /* Initialization Error */

   Error_Handler();

  }

  

 /* Disable HSI to reduce power consumption since MSI is used from that point */

 __HAL_RCC_HSI_DISABLE();

  

}

void SystemClock_Config(void)

{

 RCC_OscInitTypeDef RCC_OscInitStruct = {0};

 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

 /** Initializes the CPU, AHB and APB busses clocks 

 */

 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;

 RCC_OscInitStruct.MSIState = RCC_MSI_ON;

 RCC_OscInitStruct.MSICalibrationValue = 0;

 RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5;

 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;

 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

 {

   Error_Handler();

 }

 /** 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();

  }

 PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_LPTIM1;

 PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;

 PeriphClkInit.Lptim1ClockSelection = RCC_LPTIM1CLKSOURCE_PCLK;

 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)

 {

   Error_Handler();

 }

 /** Configure the main internal regulator output voltage 

 */

 if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)

 {

  Error_Handler();

 }

}

TDK
Guru

It sure sounds like your clock isn't what you expect it to be after low power mode. I know you posted your code, but have you verified the clock is correct after exiting low power mode by looking at the MCO output or blinking an LED or something? Sure smells like a clock configuration issue.

If you feel a post has answered your question, please click "Accept as Solution".

I get system core clock after wake up by HAL_RCC_GetHCLKFreq() and see that clock set correctly.