cancel
Showing results for 
Search instead for 
Did you mean: 

Apparent bug in CubeMX clock generation

mjones
Associate
Posted on November 08, 2014 at 01:47

I seem to have found a bug in the clock configuration of the CubeMX software (Version 4.4.0, the latest as far as I can tell). On an STM32F407, I am setting the SYSCLK to use the PLL with the PLL source being the HSE (a 25MHz crystal is attached). However, in the SystemClock_Config function, it is adding the RCC_OSCILLATORTYPE_HSI to RCC_OscInitStruct.OscillatorType. When HAL_RCC_OscConfig is called, it returns HAL_ERROR because it tries to turn off the HSI oscillator while still running from it. This in turn causes the HAL_RCC_ClockConfig call to fail, and so the micro continues running directly from the HSI oscillator at 16 MHz. If I manually remove the RCC_OSCILLATORTYPE_HSI flag, everything runs as expected.

At least one cause of this error seems to be changing the PLL source to HSE and then to HSI through multiple executions of CubeMX. After much experimentation, I have managed to recreate the error with a minimal configuration example. I have attached a pair of CubeMX configuration files to demonstrate the problem. The following steps need to be followed to recreate it: 1. Open the file clockbug3.ioc 2. Generate code 3. Close CubeMX At this point the generated SystemClock_Config looks like this (which is correct):

void
SystemClock_Config(
void
)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
__PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
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 = 25;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = 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_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
}

Continuing: 4. Open the file clockbug3.ioc again 5. On the clock configuration tab: a. Change the PLL source Mux to HSI b. Set HCLK to 168 (press enter to recalculate) 6. Generate code 7. Close CubeMX 8. Open the file clockbug3.ioc for a third time 9. On the clock configuration tab: a. Change PLL source Mux back to HSE b. Set HCLK to 168 (press enter to recalculate) Generate code At this point the generated SystemClock_Config looks like this (which is incorrect, note the addition of the RCC_OSCILLATORTYPE_HSI flag):

void
SystemClock_Config(
void
)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
__PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|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 = 25;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = 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_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
}

The file clockbug3-bad.ioc is the final state of the configuration file after following these steps. Note that closing and restarting CubeMX seems to be necessary to cause this error. Once a configuration becomes ''corrupted'', I have yet to find a way to fix it. For now, I am working around it by manually removing the RCC_OSCILLATORTYPE_HSI flag.
2 REPLIES 2
Posted on November 08, 2014 at 02:18

RCC_OscInitStruct.PLL.PLLQ = 4;

That looks bogus, it'll be clocking 48 MHz logic (USB, RND, HASH, SDIO) at 84 MHz

PLLQ should be 7 for a PLL/VCO at 336 MHz
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mjones
Associate
Posted on November 08, 2014 at 20:47

You're right that does appear bogus.  However, the relevant option on the Clock Configuration tab of CubeMX is greyed out, presumably because none of the devices that use that clock are enabled.  I can force CubeMX to generate the proper value by enabling USB, changing the value to 7, and then disabling USB again.  That does not address my original issue though, which is the spurious RCC_OSCILLATORTYPE_HSI flag being passed to the HAL_RCC_OscConfig function by the CubeMX-generated SystemClock_Config code.