STM Nucleo F030R8 (M0) External Xtal

29 Jan 2015

I tried various solutions (F401) and none worked on my F030R8. I even removed the 8Mhz xtal and caps from the STLink CPU and soldered it to the application Xtal (broken Nucleo), with the zero ohms on R37/R37, but the baud rate still was temperature sensitive, because the module use the internal RC osc. With the ztal and caps from a 'known good' solution I was sure it is not a Xtal / capacitor problem.

Some Nucleo modules UARTS worsk fine with the RC osc, but some the internal RC oscillator just not ''good enough'. The data sheet however shows the RC osc have a 'adjustment', but MBED just write 16 to this register, so it is posible to 'adjust' it, but I needed this to work from very cold to very hot.

I then created an project using STMCUBEMX and ported the MBED porject, but the same problem accur, it always used the internal RC osc,

Bebugging and (single step) showed that the it always revert to HSI, not using HSE. I then had to change the code generated by CUBEMX and got it working, but the code generated never works for the R030R8 nor the xx51K6T (my design), and I have tried all posible options, I am very confident that ST have a 'bug' here

This is the modified function, it works for both my XCUBMX project (51K6T) and the Nucleo F030R8 (MBED).

One note: The HAL_RCC_OscConfig always fails , even with this modification, not sure why, maybe someone can comment on this

Note:

<<code

  1. define USE_HSE <</code>>

need to be added to your project, and add this on start-up

<<code /* Configure the system clock */ SystemClock_Config(); initialise 'this' setup(); just to be sure SystemClock_Config(); bla - bla - bla

/ ---------------

  • System Clock Configuration
  • / void SystemClock_Config(void) { int error = 0; RCC_OscInitTypeDef RCC_OscInitStruct; RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_PeriphCLKInitTypeDef PeriphClkInit;

RCC_OscInitStruct.HSICalibrationValue = 16;

  1. ifdef USE_HSE RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  2. else RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  3. endif RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  4. ifdef USE_HSE RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  5. else RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  6. endif RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL4; RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) error += 1;

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) error += 2;

PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_I2C1; PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_SYSCLK; PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_SYSCLK; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) error += 4;

This output the 'source' on the PA8 pin of the CPU .. use only one, else the last one shall override the prev HAL_RCC_MCOConfig(RCC_MCO, RCC_MCOSOURCE_HSE, RCC_MCO_NODIV); HAL_RCC_MCOConfig(RCC_MCO, RCC_MCOSOURCE_HSI, RCC_MCO_NODIV); HAL_RCC_MCOConfig(RCC_MCO, RCC_MCOSOURCE_SYSCLK, RCC_MCO_NODIV);

SYSCFG_CLK_ENABLE(); if (error != 0) {

  1. ifdef USE_HSE debugger.printf (" >> HSE ..");
  2. else debugger.printf (" >> HSI ..");
  3. endif if ((error & 0x01) != 0) debugger.printf (" HAL_RCC_OscConfig Error! \n"); if ((error & 0x02) != 0) debugger.printf (" HAL_RCC_ClockConfig Error! \n"); if ((error & 0x04) != 0) debugger.printf (" HAL_RCCEx_PeriphCLKConfig Error! \n"); } } <</code>>

Just could not get the ">>code' working on the webapge, tried a few time.. Hope this help.