cancel
Showing results for 
Search instead for 
Did you mean: 

Configure clock at runtime on STM32F401CCU6 causes lockup/crash?

Zaphod
Associate II

I have an STM32F401CCU6 with an 25MHz ext. oscillator. I believe the internal RC oscillator is 16MHz. I have tried to configure to use the internal oscillator and as well as the ext. one with no success. Please note that my code _works_ if I don't do any clock configuration at runtime but just use the default settings. My code is below. In my code I have a delay(6000) in the main function. With a delay of 6000 the LED stays lit up when I turn power on. If I set the delay to 5000 the LED barely flashes ON and then stays OFF. Based on this I assume it is crashing or getting stuck some time AFTER the call to set up the clock. The systemClock_config function is based on the STM32CubeF4 [1] STM32F401-Discovery/. I am using the startup_stm32f401xc.s, system_stm32f4xx.c, and STM32F401VCTx_FLASH.ld files from the same folder.

Note that I currently don't have debugger attached to this target so I cannot step through.

Any ideas what I am missing? Do I need to do something more? The values I used for the clock configuration is what the ST clock configuration tool (xls) spit out.

Appreciate any insight!

#include "stm32f4xx_hal.h"
 
static void init_LEDs(void);
static void systemClock_config(void);
static void delay(unsigned int delay);
 
int main(void)
{
    systemClock_config();
    init_LEDs();
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
    delay(6000);
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
}
 
static void init_LEDs(void)
{
     __HAL_RCC_GPIOC_CLK_ENABLE();
    GPIO_InitTypeDef BoardLEDs;
    BoardLEDs.Mode = GPIO_MODE_OUTPUT_PP;
    BoardLEDs.Pin = GPIO_PIN_13;
    HAL_GPIO_Init(GPIOC, &BoardLEDs);
}
 
/**
  * @brief  System Clock Configuration
  *         The system Clock is configured as follow : 
  *            System Clock source            = PLL (HSE)
  *            SYSCLK(Hz)                     = 84000000
  *            HCLK(Hz)                       = 84000000
  *            AHB Prescaler                  = 1
  *            APB1 Prescaler                 = 2
  *            APB2 Prescaler                 = 1
  *            HSE Frequency(Hz)              = 25000000
  *            PLL_M                          = 25
  *            PLL_N                          = 336
  *            PLL_P                          = 4
  *            PLL_Q                          = 7
  *            VDD(V)                         = 3.3
  *            Main regulator output voltage  = Scale2 mode
  *            Flash Latency(WS)              = 2
  * @param  None
  * @retval None
  */
static void systemClock_config(void)
{
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
 
    /* 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 HSE Oscillator and activate PLL with HSE as source */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    //RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    //RCC_OscInitStruct.HSEState = RCC_HSE_OFF;
    //RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    //RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
    RCC_OscInitStruct.PLL.PLLM = 25;
    //RCC_OscInitStruct.PLL.PLLM = 16;
    RCC_OscInitStruct.PLL.PLLN = 336;
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
    RCC_OscInitStruct.PLL.PLLQ = 7;
    HAL_RCC_OscConfig(&RCC_OscInitStruct);
 
    /* 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_DIV4;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
    HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
}

[1] https://github.com/STMicroelectronics/STM32CubeF4

4 REPLIES 4
TDK
Guru

You should never return from main. Put an infinite loop at the end.

How is delay defined? Note that the compiler is free to optimize out loops that have no effect.

Is the LED on when PC13 is low or high?

PC13 in particular is powered from the power switch and is limited in current supply (3mA total) capacity per the datasheet. The datasheet says it should not be used to drive LEDs. How much current are you expecting it to source or sink?

There are additional fields in GPIO_InitTypeDef that you are not initializing that could lead to undefined behavior. Typically this is handled by initializing it with:

GPIO_InitTypeDef BoardLEDs = {0};

Might not be any of those, but would be good to fix them to narrow down possibilities. The clock initialization part seems fine.

If you feel a post has answered your question, please click "Accept as Solution".
Zaphod
Associate II
  1. Return from main: Yes, I know. This was just testing/narrow down the issue. In my working code I have which flashes the LED:
int main(void)
{
    //systemClock_config();
    init_LEDs();
    while(1)
    {
        HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);
        delay(480000);
    }
}

With above code the LED is flashing (this is a Black Pill board btw where there is already a working LED connected to PC13 and is confirmed to work.

Based on this I don't think there is an issue with the code to turn the LED ON or OFF. It is more of an issue with the clock config. I have tried above code with the systemClock_config() call enabled and it doesn't work (I of course changed the delay loop to take into account the change in CPU clock). The code I posted earlier was just to narrow the problem down.

2 . Forgot to include delay code (again, just test code). Delay loop is also confirmed to work and looking at the assembly it is not optimized out (most likely due to no -Os compiler flag + volatile variable:

static void delay(unsigned int delay)
{
    volatile unsigned int i;
    for(i = 0; i < delay; ++i) {
    }
}

3 . The LED connected to PC13 is a sink so LED is ON when the signal PC13 is low.

So I know the code works fine sans the clock config so something is causing it to crash/get stuck when I configure the clock. But it does not crash/stop until it reaches the delay loop and the crash seems to occur some fixed moment after the clock config is completed.

However, I do agree that I should definitely fix the initialization of the GPIO_InitTypeDef! Thanks for catching that.

EXUE.2
ST Employee

you have missed ​"HAL_Init()" before the "systemClock_config()", ​"HAL_Init()" will do the low level initialization of MCU, the correct flow should be:

{

HAL_Init();

  SystemClock_Config();

}

Zaphod
Associate II

I tried calling HAL_Init() but that made no difference. But I found my issue and now it is working. My problem is that I used the system_stm32f4xx.c from [1] (and not from where I explained in the original posting). This system_stm32f4xx.c looks very different than the one from STM32F401-Discovery/Examples [2] folder. For example it is missing several of the initialization statements related to RCC! If I use the system_stm32f4xx.c file it works.

Thanks everyone for your help!

[1] STM32CubeF4/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c 

[2] STM32CubeF4-master/Projects/STM32F401-Discovery/Examples/