cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L496ZGT6 internal regulator output voltage

AndrewFFFF
Associate II

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?

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
SofLit
ST Employee

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 on "Accept as Solution" on the reply which solved your issue or answered your question.

View solution in original post

5 REPLIES 5
Andrew Neil
Evangelist III

@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

 

SofLit
ST Employee

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 on "Accept as Solution" on the reply which solved your issue or answered your question.

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

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 on "Accept as Solution" on the reply which solved your issue or answered your question.

 


@AndrewFFFF wrote:

 

#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


As already noted, you can't run at 40MHz with VOS2 - Therefore this code

 

	/*Configure the main internal regulator output voltage*/
	if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2) != HAL_OK)

 

needs to check that you are in the USE_20MHZ_CLOCK mode ...