SystemCoreClock config FAILS on STM32F411RE Custom PCB

Thread Starter

Brett Smith 1

Joined Jul 1, 2017
13
Hello All,
I designed a custom PCB that was supposed to run an STM32F411RET6 off an external 8Mhz cystal oscillator.
This is the first custom PCB I have done for an STM32 chip, so I am never quite sure when I am having hardware versus software errors. I have attached some pictures of my PCB below. You'll notice a few "bodges":
· One of the VCC and VDD pins were swapped in the schematic, so I cut the traces and jumped the decoupling caps. I had to replace the main MCU entirely because of this mistake.
· The BOOT0 pin was left floating, so I have a jumper wire connecting it to GND.
· The VCAP1 pin was left floating, so I have a jumper wire connecting it to VCC (still no capacitor in place).

In order to eliminate some of the guesswork, I am simply trying to configure the HSI and PLL as my application is not really THAT timing critical, plus I have all the other hardware to proof out still.

For what its worth, here are the components I selected for the HSE:
Xtal <--------------- link
Caps <--------------- link

I can connect to the chip with my StLink-V2 via SWD, and can erase & program it with the St-Link Utility.
I am programming and debugging the chip with a trial license of IAR-EWARM.
I have used one of the pre-written STM32F411 Nucleo cube projects to get an ERM motor "blinking." The code is shown below:
Code:
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/** @addtogroup STM32F4xx_HAL_Examples
* @{
*/

/** @addtogroup GPIO_IOToggle
* @{
*/

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static GPIO_InitTypeDef GPIO_InitStruct;

/* Private function prototypes -----------------------------------------------*/
static void SystemClock_Config(void);
static void Error_Handler(void);

/* Private functions ---------------------------------------------------------*/

/**
* @brief Main program
* @param None
* @retval None
*/
int main(void)
{
/* STM32F4xx HAL library initialization:
- Configure the Flash prefetch, instruction and Data caches
- Configure the Systick to generate an interrupt each 1 msec
- Set NVIC Group Priority to 4
- Global MSP (MCU Support Package) initialization
*/
HAL_Init();

/* Configure the system clock to 100 MHz */
SystemClock_Config();

/*##-1- Enable GPIOA Clock (to be able to program the configuration registers) */
__HAL_RCC_GPIOC_CLK_ENABLE();

/*##-2- Configure PA05 IO in output push-pull mode to drive external LED ###*/ 
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); 

/*##-3- Toggle PA05 IO in an infinite loop #################################*/ 
while (1)
{
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_8);

/* Insert a 100ms delay */
HAL_Delay(100);
}
}

/**
* @brief System Clock Configuration
* The system Clock is configured as follow : 
* System Clock source = PLL (HSI)
* SYSCLK(Hz) = 100000000
* HCLK(Hz) = 100000000
* AHB Prescaler = 1
* APB1 Prescaler = 2
* APB2 Prescaler = 1
* HSI Frequency(Hz) = 16000000
* PLL_M = 16
* PLL_N = 400
* PLL_P = 4
* PLL_Q = 7
* VDD(V) = 3.3
* Main regulator output voltage = Scale2 mode
* Flash Latency(WS) = 3
* @param None
* @retval None
*/
static void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;

/* Enable Power Control clock */
__HAL_RCC_PWR_CLK_ENABLE();

/* The voltage scaling allows optimizing the power consumption when the device is 
clocked below the maximum system frequency, to update the voltage scaling value 
regarding system frequency refer to product datasheet. */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);

/* Enable HSI Oscillator and activate PLL with HSI as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 0x10;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 16;
RCC_OscInitStruct.PLL.PLLN = 400;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
RCC_OscInitStruct.PLL.PLLQ = 7;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}

/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 
clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; 
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; 
if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
{
Error_Handler();
}
}

/**
* @brief This function is executed in case of error occurrence.
* @param None
* @retval None
*/
static void Error_Handler(void)
{
while(1)
{
}
}

#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{ 
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

/* Infinite loop */
while (1)
{
}
}
#endif

/**
* @}
*/

/**
* @}
*/
However, the program often crashes when I call HAL_RCC_ClockConfig() function in my main.cpp file.
If I comment out the SystemClock_Config() the program runs, but the SystemCoreClock defaults to 16Mhz.
It usually seems to fail within the stm32f4xx_hall_rcc.c file when either two of the following functions are called:

Code:
/* Update the SystemCoreClock global variable */
SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE)>> POSITION_VAL(RCC_CFGR_HPRE)];

/* Configure the source of time base considering new system clocks settings*/
HAL_InitTick (TICK_INT_PRIORITY);
Usually if I pause the CPU after hanging here it appears the CPU is in the HardFault_Handler().
Occasionally the program will manually step its way through the entire configuration, but attaching a watch on the SystemCoreClock still shows it at 16Mhz.


Any ideas as to what I should do?
 

Attachments

MrChips

Joined Oct 2, 2009
34,690
I believe you must not connect VCAP1 to VCC. It needs a capacitor of its own.
I have to look into BOOT0. I usually have this floating.

Something is strange. I'm surprised that you can even get the code to run at all.
HardFault needs to be corrected. Usually caused by bad code, memory leak, etc.

I haven't checked over everything you have posted. I will do that later when I have more time.
Can you post a hardware circuit schematic and a PCB layout?
 

Thread Starter

Brett Smith 1

Joined Jul 1, 2017
13
Thank you for your reply!
I have attached a PDF of both the schematic and the pcb layout.
Sorry I made a mistake earlier.
  • Vbat was left floating and I jumped it to Vcc.
  • Vcap is floating and does not have a capacitor connected to it.
I would edit the post above so that it is accurate, but so far I haven't figured out how.

About the attached schematic and layout:
  1. The "Glue Logic" within the Battery Cutoff is not necessary (and poorly designed) so they are not populated on the PCB. The voltage detector is simply monitoring the battery voltage and cutting off the LDO before the cell drops below 3.0V (A pull up resistor was also bodged in at the output of the voltage monitor ic)
  2. Pins 31 & 32 on the STM32F411 are swapped from how they are internally wired in the MCU. So I fried the first chip i soldered in. Those traces have been cut and the decoupling caps have been jumped to adjacent ones.
 

Attachments

MrChips

Joined Oct 2, 2009
34,690
VCAP1 must have a 2.2μF filter cap. This is the CPU power supply voltage of 1.2V.
This must never be connected to VDD.

Your PCB appears to be a multilayered board. Can you post the layout in colors?
 

Thread Starter

Brett Smith 1

Joined Jul 1, 2017
13
I can't get the layers colored and export as a PCB (gray-scale only for some reason), but here is a snapshot:
  1. Red = Top Layer
  2. Lavender = Vcc Pour
  3. Orange = Gnd Pour (It actually extend underneath all of the Vcc Pour)
  4. Blue = Bottom Layer
I am sure there are some bad ground loops in there as result of the pour. I definitely don't have enough experience to toss my hat into the ring on the "star grounding vs ground plane" debate. But all of my external signals are certainly 1Mhz and under, so I am assuming that it won't be a big deal. Regardless, all of my analog work is on a separate PCB.
I sure wish I had consulted this app note in greater detail before finalizing my board design:
Getting started with STM32F4xxxx MCU hardware development
As for the Vcap pin, I have a 2.2 uF tantalum capacitor that I will try right now. My only concern is that this cap has an ESR of 7.5 ohm, while it seems that app note calls for 2 ohm.
Although I believe that the package I am using (LQFP-64) only has 1 VCap pin. If I understand correctly, page 42 of the app note says that in this case I should a 4.7 uF tantalum with an ESR of < 1 Ohm???
 

Attachments

Thread Starter

Brett Smith 1

Joined Jul 1, 2017
13
Looks like that capacitor on vcap solved the problem!
Still going to test things out.
I jumped in the 2.2 uf cap with ESR of 7.5 oh.
I am still not convinced this is the right value, going to have to dig further.
 

Thread Starter

Brett Smith 1

Joined Jul 1, 2017
13
Now I can connect to it and it seems to work just fine (still having trouble using the MBed stack due to problems with the HSE though...)
I am updating the design right now and I am still confused what the correct capacitor value should be for this pin.

Reading this app note on page 8 it says that:

Vcap2 is not available on all packages. In that case, a single 100nF decoupling capacitor is connected to Vcap1.

I believe this my case, as the LQFP-64 package I am using does only have 1 vcap pin. However later on the app note on page 9 it says

When the voltage regulator is enabled, Vcap1 and Vcap2 pins must be connected to 2*2.2uF LowESR < 2Ohm ceramic capacitor
(or 1*4.7 uF LowESR < 1 Ohm capacitor if only Vcap1 is provided on some packages.


Which seems contradictory. My best guess is that the 100nF cap is for a processor that has the internal regulator disabled? However, to the best of my knowledge, this pin is connected to the processors internal bus, and that you basically would never want to disable the regulator in the first place?
 
Top