cancel
Showing results for 
Search instead for 
Did you mean: 

In STM32CubeIDE, how does one determine the 'Core Clock' and 'SWO Clock' rate in the Debug Configuration for a working project from source and no IOC file?

Ted Jackson
Senior
 
1 ACCEPTED SOLUTION

Accepted Solutions

 printf("\n\nCore=%d, %d MHz\n", SystemCoreClock, SystemCoreClock / 1000000);

The SWO side clock is usually determined by the debugger side interface, ie 2 MHz or whatever, and it then programs the chip side SWO baud rate and encoding scheme to relate the two. ie divisor = (168000000 / 2000000) - 1

The H7 side code looked like this

//SWO current output divisor register

//This divisor value (0x000000C7) corresponds to 400Mhz

//To change it, you can use the following rule

// value = (CPU Freq/sw speed )-1

*(__IO uint32_t*)(0x5C003010) = ((SystemCoreClock / 2000000) - 1); // SWO_CODR

Other systems

TPI->ACPR = ((SystemCoreClock / 2000000) - 1); /* "Async Clock Prescaler Register". Scale the baud rate of the asynchronous output */

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

5 REPLIES 5

You look at the clock and PLL settings

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I see no mention of Core Clock or SWO Clock in SystemClock_Config() or in a typical Clock Configuration page in CubeMX. Is there no utility to just measure that resultant clock rate? Can you be more specific please?

 printf("\n\nCore=%d, %d MHz\n", SystemCoreClock, SystemCoreClock / 1000000);

The SWO side clock is usually determined by the debugger side interface, ie 2 MHz or whatever, and it then programs the chip side SWO baud rate and encoding scheme to relate the two. ie divisor = (168000000 / 2000000) - 1

The H7 side code looked like this

//SWO current output divisor register

//This divisor value (0x000000C7) corresponds to 400Mhz

//To change it, you can use the following rule

// value = (CPU Freq/sw speed )-1

*(__IO uint32_t*)(0x5C003010) = ((SystemCoreClock / 2000000) - 1); // SWO_CODR

Other systems

TPI->ACPR = ((SystemCoreClock / 2000000) - 1); /* "Async Clock Prescaler Register". Scale the baud rate of the asynchronous output */

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Normally you tell the debugger or SWV Viewer window the speed you're clocking the core, ie 168 MHz, 80 MHz, or whatever and it figures the baud rate prescaler based on it's connection speed, and writes that into the internal registers it needs to configure on the core side. The debugger writer is typically responsible for this behind the curtain stuff, but doesn't necessarily know your chosen clocking scheme as this is highly variable and flexible.

You can unpack the RCC and PLL settings, based on the source clock (HSE, HSI) and simple multiplication and division of integers. In most examples the clock settings/expectations are explained in the comments

/**
  * @brief  System Clock Configuration
  *         The system Clock is configured as follow :
  *            System Clock source            = PLL (HSE)
  *            SYSCLK(Hz)                     = 216000000
  *            HCLK(Hz)                       = 216000000
  *            AHB Prescaler                  = 1
  *            APB1 Prescaler                 = 4
  *            APB2 Prescaler                 = 2
  *            HSE Frequency(Hz)              = 25000000
  *            PLL_M                          = 25
  *            PLL_N                          = 432
  *            PLL_P                          = 2
  *            PLL_Q                          = 9
  *            VDD(V)                         = 3.3
  *            Main regulator output voltage  = Scale1 mode
  *            Flash Latency(WS)              = 7
  * @param  None
  * @retval None
  */
static void SystemClock_Config(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;
 
  /* Enable HSE Oscillator and activate PLL with HSE as source */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 25;
  RCC_OscInitStruct.PLL.PLLN = 432;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 9;
  if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
 
  /* activate the OverDrive to reach the 216 Mhz Frequency */
  if(HAL_PWREx_EnableOverDrive() != 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_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
  if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7) != HAL_OK)
  {
    Error_Handler();
  }
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

 printf("\n\nCore=%d, %d MHz\n", SystemCoreClock, SystemCoreClock / 1000000);

That did the trick. Put that number in as Debugger->Serial Wire Viewer (SWV)->Core Clock. Left SWO Clock: at its default of 2000 and got good text in Port 0 in the SWV ITM Data Console view. Any way to keep recording enabled from run to run? Thx