cancel
Showing results for 
Search instead for 
Did you mean: 

UART RX does not work after changing clock from HSI to MSI

SAkhi.951
Associate III

MCU - STM32L431RC; HAL drivers ver 1.13.

After switching clock from HSI to MSI 16 -> 32 MHz,

CubeMX generated system Clock setup does not work.

When trying to send data to STM constantly getting "Noise error" and rarely 1st byte is received via ISR. TX works ok. DMA/IT does not matter.

UART 2 and UART 3 are tested with baudrate 115200.

Working clock setup:

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_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 busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  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_RTC|RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_USART2
                              |RCC_PERIPHCLK_USART3;
  PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_HSI;
  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
  PeriphClkInit.Usart3ClockSelection = RCC_USART3CLKSOURCE_PCLK1;
  PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
  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();
  }

Not working clock setup:

RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
 
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI|RCC_OSCILLATORTYPE_LSI;
  RCC_OscInitStruct.MSIState = RCC_MSI_ON;
  RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_10;
  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_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_1) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_USART2
                              |RCC_PERIPHCLK_USART3;
  PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
  PeriphClkInit.Usart3ClockSelection = RCC_USART3CLKSOURCE_SYSCLK;
  PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
  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();
  }

Any suggestions?

9 REPLIES 9

Read out and check the MSI trim setting (RCC_ICSCR.MSITRIM).

What is the hardware you are using for testing?

JW

TDK
Guru

Can you view the signal on the line? Almost certainly the clock rate is off, especially if the first byte is sometimes received correctly. MSI doesn't have great accuracy or stability.

You can try adjusting 115200 up or down by a few percent. Or adjusting RCC_MSICALIBRATION_DEFAULT.

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

MSITRIM is 135.

What is the hardware you are using for testing? - not sure what you refer to.

I am using STM32L431RC MCU on a custom made board, UART communication via UART dongle connected to PC.

I have changed Calibration value to 10 and it started to work, Thanks!

Why 10? And why was it 135?

Just in case anybody will come here in the future:

> What is the hardware you are using for testing? - not sure what you refer to.

Both the board - to know if it's a "known good" one such as Nucleo or Disco, or your own; and also to:

> UART communication via UART dongle connected to PC

maybe with more precise explanation what "dongle" exactly is, and also whether any level conversion is involved.

JW

TDK
Guru

> MSITRIM is 135.

Are you sure about this? Default on powerup per the RM is 0. Default in CubeMX appears to be 0 as well. Perhaps you're reading MSICAL instead?

https://github.com/STMicroelectronics/STM32CubeL4/blob/master/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc.h#L245

It's odd that MSITRIM only allows calibration in one direction, since the default value is 0. Whereas the default HSITRIM is centrally located so it can be both increased and decreased.

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

You are correct, it was MSICAL value. MSITRIM is 0.

10 was just a random choice.

Is there any instruction how to adjust calibration value ?

As to "dongle" - it is USB to TTL serial cable.

TDK
Guru

> Is there any instruction how to adjust calibration value ?

It is nonlinear, you will just need to adjust and verify. Note that having MSICAL + MSITRIM >= 256 will cause it to overflow and decrease the effective value. So it is possible to adjust both up and down.

https://www.st.com/resource/en/application_note/dm00210926-how-to-calibrate-stm32l4-series-microcontrollers-internal-rc-oscillator-stmicroelectronics.pdf

0693W00000DmYwWQAV.png

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