0

How can we get an Stm32f103c8 running 72MHz with Arduino IDE (STM32duino)?

We have custom designed a PCB using the chip from the question. We are able to get it running at 72MHz using STM32CubeIDE. The clock configuration is shown below.

Clock ConfigurationClock Configuration PinoutPinout

It does run at 72MHz from CubeIDE. The Stm32f103C8 runs at 48MHz on default in ArduinoIDE.

We're using the stm32duino core (https://github.com/stm32duino/BoardManagerFiles/blob/main/package_stmicroelectronics_index.json).

I've copied this code from main.c to the sketch in Arduino. And manage to change the clock speed from 48MHz to 36MHz. I find it exciting that the clock speed did change but it's half of what I need. Now, I am very confused. Even when matching all of the settings with CubeIDE which says it should run at 72MHz, it is running at 36MHz.

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USB_PCD_Init(void);


void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV2;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses 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_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }

  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
  PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}


static void MX_GPIO_Init(void)
{
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
}

The 16MHz oscillator is connected to PD0 and PD1 as specified in the datasheet.

Update 2023May25: After using the app "Everything", I found stm32f1xx_hal_rcc.h and it shows the rcc stuff: For RCC->CR

#define __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(_HSICALIBRATIONVALUE_) \
      (MODIFY_REG(RCC->CR, RCC_CR_HSITRIM, (uint32_t)(_HSICALIBRATIONVALUE_) << RCC_CR_HSITRIM_Pos))

#define __HAL_RCC_HSE_CONFIG(__STATE__)                                     \
                    do{                                                     \
                      if ((__STATE__) == RCC_HSE_ON)                        \
                      {                                                     \
                        SET_BIT(RCC->CR, RCC_CR_HSEON);                     \
                      }                                                     \
                      else if ((__STATE__) == RCC_HSE_OFF)                  \
                      {                                                     \
                        CLEAR_BIT(RCC->CR, RCC_CR_HSEON);                   \
                        CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP);                  \
                      }                                                     \
                      else if ((__STATE__) == RCC_HSE_BYPASS)               \
                      {                                                     \
                        SET_BIT(RCC->CR, RCC_CR_HSEBYP);                    \
                        SET_BIT(RCC->CR, RCC_CR_HSEON);                     \
                      }                                                     \
                      else                                                  \
                      {                                                     \
                        CLEAR_BIT(RCC->CR, RCC_CR_HSEON);                   \
                        CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP);                  \
                      }                                                     \
                    }while(0U)

#define __HAL_RCC_GET_FLAG(__FLAG__) (((((__FLAG__) >> 5U) == CR_REG_INDEX)?   RCC->CR   : \
                                      ((((__FLAG__) >> 5U) == BDCR_REG_INDEX)? RCC->BDCR : \
                                                                              RCC->CSR)) & (1U << ((__FLAG__) & RCC_FLAG_MASK)))

For RCC->CFGR

#define __HAL_RCC_PLL_CONFIG(__RCC_PLLSOURCE__, __PLLMUL__)\
          MODIFY_REG(RCC->CFGR, (RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL),((__RCC_PLLSOURCE__) | (__PLLMUL__) ))

#define __HAL_RCC_GET_PLL_OSCSOURCE() ((uint32_t)(READ_BIT(RCC->CFGR, RCC_CFGR_PLLSRC)))

#define __HAL_RCC_SYSCLK_CONFIG(__SYSCLKSOURCE__) \
                  MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, (__SYSCLKSOURCE__))

#define __HAL_RCC_GET_SYSCLK_SOURCE() ((uint32_t)(READ_BIT(RCC->CFGR,RCC_CFGR_SWS)))

#define __HAL_RCC_MCO1_CONFIG(__MCOCLKSOURCE__, __MCODIV__) \
                 MODIFY_REG(RCC->CFGR, RCC_CFGR_MCO, (__MCOCLKSOURCE__))
Kuldeep J
  • 382
  • 5
  • 12
  • Post the contents of RCC registers, would really help a lot. Control register and clock configuration register. They contain clock selection configuration. `RCC->CR` and `RCC->CFGR`. Whatever is wrong, we should almost definitely see it there. Nothing in your code stands out as odd. – Ilya May 24 '23 at 13:02
  • I believe I found the RCC->CR and RCC->CFGR pieces. – Burgger Big May 26 '23 at 02:15
  • That's completely not what I asked. I just wanted values after things are set. Like RCC->CR = 0x12345678 and RCC->CFGR = 0x87654321 (meaning the value they contain, it's not an assignment). The problem would have been immediately visible there. – Ilya May 26 '23 at 08:15
  • Still have no idea what you are asking, but I did manage to solve my problem. – Burgger Big May 26 '23 at 09:37
  • Yeah but it's important you get what reading a register value is. It would simplify your debugging to 10-minute process in case of such a problem with no or almost no source code reading. Basically, you want to know the value inside RCC->CR and RCC->CFGR. These registers contain clock settings, it's them that all this HAL setup ultimately writes to. They're just two 32-bit numbers, where every bit has a function. One of the bits enables HSE (if that bit is 1, HSE is enabled, otherwise not), a group of other ones inside that number sets clock dividers, etc. Setting those bits is what HAL does. – Ilya May 26 '23 at 11:48

1 Answers1

0

Finally, I got it working by changing the HSE value from the default value. It's from C:\Users<User name>\AppData\Local\Arduino15\packages\STMicroelectronics\hardware\stm32\2.5.0\system\STM32F1xx and the file name is stm32f1xx_hal_conf_default.h

The line is #define HSE_VALUE 8000000U And I changed it to #define HSE_VALUE 16000000U cause I am using a 16MHz oscillator. That seems to fix my problem. As the F_CPU tells me, it's at 72MHz. However, I need my partner to check whether it is running faster or is lying.

STM32duino should allow people to have easier access to define these values. The version update makes things all over the place.