Skip to main content
Associate III
February 6, 2024
Solved

STM32L496ZGT6 internal regulator output voltage

Hi

I have a problem with my board with STM32L496ZGT6.

Some boards works fine (so.. i think there isn't a project problem) some boards are in loop during the power on.

I exaplin better:

Here a function in main.cpp:

 

	/*Configure the main internal regulator output voltage...............................................*/
	if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2) != HAL_OK)
	{
		_Error_Handler(__FILE__, __LINE__);
	}
void _Error_Handler(char *, int)
{
	while(1){}
}

 

 If I comment:

 

	/*Configure the main internal regulator output voltage...............................................*/
	/*
	if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2) != HAL_OK)
	{
		_Error_Handler(__FILE__, __LINE__);
	}
	/*.....

 

The board power on reguarly so it means:

 

HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2) != 0

 

This is esay but why does this happen?

Hardware problem?

Here the function HAL_PWREx_ControlVoltageScaling:

 

HAL_StatusTypeDef HAL_PWREx_ControlVoltageScaling(uint32_t VoltageScaling)
{
 uint32_t wait_loop_index = 0; 

 assert_param(IS_PWR_VOLTAGE_SCALING_RANGE(VoltageScaling));

#if defined(PWR_CR5_R1MODE)
 if (VoltageScaling == PWR_REGULATOR_VOLTAGE_SCALE1_BOOST)
 {
 /* If current range is range 2 */
 if (READ_BIT(PWR->CR1, PWR_CR1_VOS) == PWR_REGULATOR_VOLTAGE_SCALE2)
 {
 /* Make sure Range 1 Boost is enabled */
 CLEAR_BIT(PWR->CR5, PWR_CR5_R1MODE);
 
 /* Set Range 1 */
 MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE1);
 
 /* Wait until VOSF is cleared */ 
 wait_loop_index = (PWR_FLAG_SETTING_DELAY_US * (SystemCoreClock / 1000000));
 while ((wait_loop_index != 0) && (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF)))
 {
 wait_loop_index--;
 }
 if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF))
 {
 return HAL_TIMEOUT;
 } 
 } 
 /* If current range is range 1 normal or boost mode */
 else
 {
 /* Enable Range 1 Boost (no issue if bit already reset) */
 CLEAR_BIT(PWR->CR5, PWR_CR5_R1MODE);
 }
 }
 else if (VoltageScaling == PWR_REGULATOR_VOLTAGE_SCALE1)
 {
 /* If current range is range 2 */
 if (READ_BIT(PWR->CR1, PWR_CR1_VOS) == PWR_REGULATOR_VOLTAGE_SCALE2)
 {
 /* Make sure Range 1 Boost is disabled */
 SET_BIT(PWR->CR5, PWR_CR5_R1MODE);
 
 /* Set Range 1 */
 MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE1);
 
 /* Wait until VOSF is cleared */ 
 wait_loop_index = (PWR_FLAG_SETTING_DELAY_US * (SystemCoreClock / 1000000));
 while ((wait_loop_index != 0) && (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF)))
 {
 wait_loop_index--;
 }
 if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF))
 {
 return HAL_TIMEOUT;
 } 
 } 
 /* If current range is range 1 normal or boost mode */
 else
 {
 /* Disable Range 1 Boost (no issue if bit already set) */
 SET_BIT(PWR->CR5, PWR_CR5_R1MODE);
 } 
 }
 else
 {
 /* Set Range 2 */
 MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE2);
 /* No need to wait for VOSF to be cleared for this transition */
 /* PWR_CR5_R1MODE bit setting has no effect in Range 2 */ 
 }
 
#else

 /* If Set Range 1 */
 if (VoltageScaling == PWR_REGULATOR_VOLTAGE_SCALE1)
 {
 if (READ_BIT(PWR->CR1, PWR_CR1_VOS) != PWR_REGULATOR_VOLTAGE_SCALE1)
 {
 /* Set Range 1 */
 MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE1);
 
 /* Wait until VOSF is cleared */ 
 wait_loop_index = (PWR_FLAG_SETTING_DELAY_US * (SystemCoreClock / 1000000));
 while ((wait_loop_index != 0) && (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF)))
 {
 wait_loop_index--;
 }
 if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF))
 {
 return HAL_TIMEOUT;
 }
 }
 }
 else
 {
 if (READ_BIT(PWR->CR1, PWR_CR1_VOS) != PWR_REGULATOR_VOLTAGE_SCALE2)
 {
 /* Set Range 2 */
 MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE2);
 /* No need to wait for VOSF to be cleared for this transition */
 }
 }
#endif 
 
 return HAL_OK;
} 

 

Any advice?

 

 

This topic has been closed for replies.
mƎALLEm
mƎALLEmBest answer
ST Technical Moderator
February 6, 2024

Hello,

According to the RM, the dafault PWR config after reset is VOS1:

SofLit_0-1707216889172.png

And there is a sequence to switch from VOS1 to VOS2:

SofLit_0-1707216566442.png

Also what is your system frequency? You can't exceed 26MHz at VOS2!

To give better visibility on the answered topics, please click "Best answer" on the reply which solved your issue or answered your question.

5 replies

Andrew Neil
Super User
February 6, 2024

@AndrewFFFF wrote:

Some boards works fine (so.. i think there isn't a project problem)


That's not an entirely safe assumption: it could be that the design is marginal - so some boards just work, while others just fail ...

The PWR_REGULATOR_VOLTAGE_SCALE2 has a number of limitations - are you sure you are strictly within  them all?

https://www.st.com/resource/en/application_note/an4978-design-recommendations-for-stm32l4xxxx-with-external-smps-for-ultra-low-power-applications-with-high-performance-stmicroelectronics.pdf

 

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
mƎALLEm
mƎALLEmBest answer
ST Technical Moderator
February 6, 2024

Hello,

According to the RM, the dafault PWR config after reset is VOS1:

SofLit_0-1707216889172.png

And there is a sequence to switch from VOS1 to VOS2:

SofLit_0-1707216566442.png

Also what is your system frequency? You can't exceed 26MHz at VOS2!

To give better visibility on the answered topics, please click "Best answer" on the reply which solved your issue or answered your question.
Associate III
February 6, 2024

Thank you for your fast answers:

I "inherited" this board and i didn't project this board, so i need time to replay your question.

Here in main.cpp:

#if USE_20_MHZ_CLOCK
	//For 20Mhz core clock freq
	RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV4;
	RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
	RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
#endif

#if USE_40_MHZ_CLOCK
	//For 40Mhz core clock freq
	RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2;
	RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV8;
	RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
#endif

I think 40_MHz for debug mode

About the hardware i share some photo about the power supply:

stm10.jpgstm8.jpgstm7.jpgstm4.jpgstm3.jpgstm2.jpgstm1.jpg

mƎALLEm
ST Technical Moderator
February 6, 2024

I've already said: you need to implement the sequence to switch from VOS1 to VOS2.

To me it's not a HW issue for the moment. You need to implement the sequence as described in the RM.

To give better visibility on the answered topics, please click "Best answer" on the reply which solved your issue or answered your question.