cancel
Showing results for 
Search instead for 
Did you mean: 

Slow Clock at powerup requires reset each time

Jeremy Vance
Associate II
Posted on June 08, 2018 at 20:57

Hello,

   I'm having an odd time with a board using the STM32F746VGT6 microcontroller that it requires that I reset the board each time that I power it up.  I have several of these and the phenomenon only occurs on about half of the boards.  When it does, it requires shorting the reset pin to ground as I don't have a reset button on this design.  I have checked solder joints of the 8MHz crystal and caps as well as the reset circuit (used from stm32f746 discovery board design).  The code is generated from CUBEMX.  It appears to run about 10 times as slow.  I'm trying to run the main PLL clock output at 192MHz.  Here is my startup code for the clock:

void SystemClock_Config(void)

{

RCC_OscInitTypeDef RCC_OscInitStruct;

RCC_ClkInitTypeDef RCC_ClkInitStruct;

RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;

/**Configure the main internal regulator output voltage

*/

__HAL_RCC_PWR_CLK_ENABLE();

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

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

*/

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;

RCC_OscInitStruct.HSEState = RCC_HSE_ON;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

RCC_OscInitStruct.PLL.PLLM = 8;

RCC_OscInitStruct.PLL.PLLN = 384;

RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;

RCC_OscInitStruct.PLL.PLLQ = 8;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

/**Activate the Over-Drive mode

*/

if (HAL_PWREx_EnableOverDrive() != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

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

RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV4;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_6) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2

| RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_I2C1

| RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_SDMMC1

| RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_CLK48;

PeriphClkInitStruct.PLLSAI.PLLSAIN = 316;

PeriphClkInitStruct.PLLSAI.PLLSAIR = 2;

PeriphClkInitStruct.PLLSAI.PLLSAIQ = 7;

PeriphClkInitStruct.PLLSAI.PLLSAIP = RCC_PLLSAIP_DIV8;

PeriphClkInitStruct.PLLSAIDivQ = 1;

PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_2;

PeriphClkInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI;

PeriphClkInitStruct.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;

PeriphClkInitStruct.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;

PeriphClkInitStruct.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;

PeriphClkInitStruct.I2c2ClockSelection = RCC_I2C2CLKSOURCE_PCLK1;

PeriphClkInitStruct.Clk48ClockSelection = RCC_CLK48SOURCE_PLL;

PeriphClkInitStruct.Sdmmc1ClockSelection = RCC_SDMMC1CLKSOURCE_CLK48;

if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

/**Configure the Systick interrupt time

*/

HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000);

/**Configure the Systick

*/

HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

/* SysTick_IRQn interrupt configuration */

HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

}

Can someone help me please?

Thanks,

Jeremy

#cpu-clock-frequency #stm32f746
10 REPLIES 10
john doe
Lead
Posted on June 09, 2018 at 23:51

what do you have HSE_VALUE set to

Posted on June 09, 2018 at 23:59

I have HSE_VALUE set to 8000000.

I have the HSE timeout set to 2000ms

The System clock is set to 192000000.

On Sat, Jun 9, 2018, 5:52 PM john doe <st-microelectronics@jiveon.com>

Posted on June 10, 2018 at 04:04

So probably 16 MHz HSI (so 12x slower)

Clear the auto/local variables

RCC_OscInitTypeDef RCC_OscInitStruct = {0};

RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

Surprised it wouldn't plough into the Error_Handler(), does that return?

Check your actually test the oscillator source __HAL_RCC_GET_PLL_OSCSOURCE()

Check define for HSE_TIMEOUT_VALUE

Check clocking of SysTick

Do you have a USART you can actually report internal status/functionality?

Have you quantified the time to start the HSE using some simple code to enable HSE via RCC, and waiting for HSE RDY. Compare/contrast between working/non-working examples.

Change the caps on oscillator see if that improves situation.

Quantify rise time of supply.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
T J
Lead
Posted on June 10, 2018 at 09:15

if you have to use a reset chip,

this one works well  2.94V threshold and 1.2S delay.

0690X0000060L8nQAE.png
Posted on June 11, 2018 at 22:25

Thanks Clive for the helpful suggestions.  Here are my findings so far:

I have cleared out the local variables and no help.

The Error Handler has a breakpoint and it never hits.  Error handler is just a while(1) loop as default anyway.

HSE_TIMEOUT_VALUE  = HSE_STARTUP_TIMEOUT = 2000U

I'll check what the OSCSource comes back at.

What is the best way to check SysTick clocking?

I do have an internal UART that communicates with another controller it's status.

Do you have sample code to quantify HSE enabling and HSE ready?  I can't use systick for that because it isn't enabled yet.

I currently have 20pF caps on the 8.00MHz (ABM3B-8.000MHZ-B2-T). These are the same crystals and caps I used on a very stable F407 board so I assumed the same would be appropriate since the signal wire lengths are within 2% between the boards.  Also inline resistor of 220 ohms on one leg of the crystal.

I'll measure the rise time of the supply on my scope and see how long it takes to get up to spec.  The input voltage is a 12V battery and it is being stepped down to 3.3V through two linear regulators.  Shouldn't be long.  I'll post more info soon.

Posted on June 11, 2018 at 22:39

Ok

Is something precluding you from outputting some diagnostic information so you understand the state of the device?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on June 11, 2018 at 22:54

I guess lack of forethought.  No, actually I didn't think UART would work because nothing else works at this speed except for slowly blinking some status LEDs.  I'll give it a go.  If the controller can detect it's own state of speed then I could just tell it to reset or re-init the HSE clock right?

Posted on June 11, 2018 at 22:55

Thanks for the suggestion TJ.  I'll work it into the next design as a backup.  It can be unpopulated if I can figure this out otherwise.

Posted on June 12, 2018 at 00:22

Looks like you added to the post, the script doesn't seem to refresh.

I have built things in the past to time the HSI/HSE up time

This is what I have to dump internals,

//****************************************************************************

void CORECheck(void) //

mailto:sourcer32@gmail.com

{

  uint32_t cpuid = SCB->CPUID;

  uint32_t var, pat;

  printf('CPUID %08X DEVID %03X REVID %04X\n', cpuid, DBGMCU->IDCODE & 0xFFF, (DBGMCU->IDCODE >> 16) & 0xFFFF);

  pat = (cpuid & 0x0000000F);

  var = (cpuid & 0x00F00000) >> 20;

  if ((cpuid & 0xFF000000) == 0x41000000) // ARM

  {

    switch((cpuid & 0x0000FFF0) >> 4)

    {

      case 0xC20 : printf('Cortex M0 r%dp%d\n', var, pat); break;

      case 0xC60 : printf('Cortex M0+ r%dp%d\n', var, pat); break;

      case 0xC21 : printf('Cortex M1 r%dp%d\n', var, pat); break;

      case 0xC23 : printf('Cortex M3 r%dp%d\n', var, pat); break;

      case 0xC24 : printf('Cortex M4 r%dp%d\n', var, pat); break;

      case 0xC27 : printf('Cortex M7 r%dp%d\n', var, pat); break;

      default : printf('Unknown CORE\n');

    }

  }

  else

    printf('Unknown CORE IMPLEMENTER\n');

}

//****************************************************************************

// FPU Programmer Model

//

https://community.st.com/external-link.jspa?url=http%3A%2F%2Finfocenter.arm.com%2Fhelp%2Findex.jsp%3Ftopic%3D%2Fcom.arm.doc.ddi0489b%2FChdhfiah.html

void FPUCheck(void) //

mailto:sourcer32@gmail.com

{

  uint32_t mvfr0;

  printf('%08X %08X %08X\n%08X %08X %08X\n',

    *(volatile uint32_t *)0xE000EF34,   // FPCCR  0xC0000000

    *(volatile uint32_t *)0xE000EF38,   // FPCAR

    *(volatile uint32_t *)0xE000EF3C,   // FPDSCR

    *(volatile uint32_t *)0xE000EF40,   // MVFR0  0x10110021 vs 0x10110221

    *(volatile uint32_t *)0xE000EF44,   // MVFR1  0x11000011 vs 0x12000011

    *(volatile uint32_t *)0xE000EF48);  // MVFR2  0x00000040

  mvfr0 = *(volatile uint32_t *)0xE000EF40;

  switch(mvfr0)

  {

    case 0x10110021 : printf('FPU-S Single-precision only\n'); break;

    case 0x10110221 : printf('FPU-D Single-precision and Double-precision\n'); break;

    default : puts('Unknown FPU');

  }

}

//****************************************************************************

void IDCODECheck(void)

{

  uint32_t idcode = DBGMCU->IDCODE & 0xFFF;

  switch(idcode)

  {

    case 0x423 :

    case 0x433 : printf('STM32F401\n'); break;

    case 0x431 : printf('STM32F411\n'); break;

    case 0x411 : printf('STM32F457\n'); break;

    case 0x413 : printf('STM32F407\n'); break;

    case 0x419 : printf('STM32F429 or F439\n'); break;

    case 0x421 : printf('STM32F446\n'); break;

    case 0x434 : printf('STM32F469\n'); break;

    case 0x441 : printf('STM32F412\n'); break;

    case 0x417 : printf('STM32L0 Cat 3\n'); break;

    case 0x447 : printf('STM32L0 Cat 5\n'); break;

    case 0x435 : printf('STM32L43xxx or L44xxx\n'); break;

    case 0x415 : printf('STM32L475xx, L476xx or L486xx\n'); break;

    case 0x461 : printf('STM32L496xx or L4A6xx\n'); break;

    case 0x462 : printf('STM32L45xxx or L46xxx\n'); break;

    case 0x470 : printf('STM32L4Rxxx or L4Sxxx\n'); break;

    case 0x449 : printf('STM32F74xxx or F75xxx\n'); break;

    case 0x451 : printf('STM32F76xxx or F77xxx\n'); break;

    case 0x450 : printf('STM32H7xx\n'); break;

    default : printf('Unknown STM32\n');

  }

}

//****************************************************************************

  printf('\n\nCore=%d, %d MHz\n', SystemCoreClock, SystemCoreClock / 1000000);

  CORECheck();

  IDCODECheck();

  FPUCheck();

  printf('APB1=%d\n', HAL_RCC_GetPCLK1Freq());

  printf('APB2=%d\n', HAL_RCC_GetPCLK2Freq());
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..