cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 - SWV print not working when using PLL to generate sysclock

ping_pong
Associate II

Hello folks,

I've been having a weird issue and haven't found anyone else with the same problem, so I figured I'd post here.

I have a project for the STM32H735 BLANK. The PCB has an 25 MHz external oscillator (ABM8W-25.0000MHZ-8-D1X-T3) used as the HSE.

When I use the 64 MHz HSI or the 25 MHz HSE without the PLL to generate the sysclock, SWV printing works great. When I run them through the PLL (I'd like to run this with a sysclk at at around 450 MHz), even if I set up the PLL to output the same clock it is given, SWV printing fails. I do not change any other aspects of the code. aside from the sysclock source. I am not forgetting to swap the sysclock on the IDE debug settings side when changing clock settings, and I know I've correctly set up ITM otherwise because I can see it when not using the PLL. Using the debugger and breakpoints, I've verified the code runs correctly for all test cases below (or at least does to the best my knowledge).

Clearly, I'm missing something.

My four test cases and results are:

  1. HSE as PLL source, PLL generates same output as input, PLL is SYSCLK source: no SWV
  2. HSI as PLL source, PLL generates same output as input, PLL is SYSCLK source: no SWV
  3. HSE as SYSCLK source: SWV works fine
  4. HSI as SYSCLK source: SWV works fine

 

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

/** Supply configuration update enable
*/
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);

// VOS0 (Voltage scale 0) allows the highest clock values (page 337 in the datasheet)
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);

// wait until the voltage scaling has taken effect (cannot change the clock before this)
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}

// configure clocks
// we use the HSI for peripherals and the HSE (External crystal for the system/cpu clock)
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSIState = RCC_HSI_DIV1;
RCC_OscInitStruct.HSICalibrationValue = 64;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

// SWAP SECTION
// 1) HSE as PLL source
// RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
// 2) HSI as PLL source
// RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;

// SWAP SECTION
// 1) PLL settings to output the same as the input HSE
// RCC_OscInitStruct.PLL.PLLM = 5;
// RCC_OscInitStruct.PLL.PLLN = 100;
// RCC_OscInitStruct.PLL.PLLP = 20;
// 2) PLL settings to output the same as the input HSI
// RCC_OscInitStruct.PLL.PLLM = 4;
// RCC_OscInitStruct.PLL.PLLN = 20;
// RCC_OscInitStruct.PLL.PLLP = 5;

RCC_OscInitStruct.PLL.PLLQ = 2;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
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_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
// SWAP SECTION
// 1 & 2) PLLCLK as SYSCLK source
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
// 3) HSE as SYSCLK source
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
// 4) HSI as SYSCLK source
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;

RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
{
Error_Handler();
}
}

 

1 ACCEPTED SOLUTION

Accepted Solutions
ping_pong
Associate II

My solution was pretty simple. The output from DIVR1 must match the SYSCLOCK. If not, it breaks. Doesn't matter what combination of divisors and prescalers are used, as long as DIVR1 matches the SYSCLOCK.

 

As a general solution, ensure that the clock source for the SWV is enabled, and that it matches the PLL (or other clock as required by the datasheet.)

View solution in original post

5 REPLIES 5
AlvyneZ
Associate

Hi, did you get a solution to this? I'm having the same problem.

SWV works perfectly with HSI and HSE directly, but not through the PLL. Trying to start the Trace errors out with the following error.

Screenshot from 2024-10-04 12-55-06.png

Where do you see this message? Which IDE or debugger?

 

HSIState setting looks to be nonsense in the top post.

Present YOUR settings, and DETAILS of YOUR board, and YOUR code.

SWV need physical connectivity of PB3/SWO and the core frequency needs to be understood by the DEBUGGER to relate the SWCLK of the pod connection, and the dividers for the SWV UART

The clocks and PLLs need to come up properly, and not fail. Perhaps print settings the STM32 thinks it's running at, so APB, AHB and MCU, etc.

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

I found that I was disabling PLL1's R output and it is the input clock for the TPIU, from the datasheet:

Screenshot from 2024-10-08 12-51-33.png

Enabling this fixed the "Failed to enable SWV configuration" error.

In the Debug Configuration, I've found that setting the Core Clock of the SWV config to the PLL output is what works when PLL1P and PLL1R are equal. When PLL1Rclk < PLL1Pclk, the Core Clock configuration in the IDE should equal the D1 domain clock used by the core.

I believe on other STM32 mcus (F & L series), the IDE's SWV core clock should equal the AHB clock.

ping_pong
Associate II

My solution was pretty simple. The output from DIVR1 must match the SYSCLOCK. If not, it breaks. Doesn't matter what combination of divisors and prescalers are used, as long as DIVR1 matches the SYSCLOCK.

 

As a general solution, ensure that the clock source for the SWV is enabled, and that it matches the PLL (or other clock as required by the datasheet.)