cancel
Showing results for 
Search instead for 
Did you mean: 

Using ITM printf on STM32H723 Nucleo board

JSchu.5
Associate II

Hi all,

I'm tying to use the ITM printf on my STM32H723 Nucleo board in my Keil project without success. I configured the HAL with CubeMX and add the initialization for the SWD_Init(). I enabled tracing in Keil but I do not get any output.

I checked:

  1. SWO solder bridge SB32 on my board.
  2. The basic clock configuration using a PWM signal.
  3. I also checked SystemCoreClock variable is set to 550 MHz.
  4. Updated STM Link Utility to newest version

I have no clue why I can't see any output. I will attach my minimal project example as zip and some screenshots of my Keil Debug config. Hope somebody can help me with this. Keil debugger status bar is red and says no "No Synchronization"

I read the following post:

https://community.st.com/s/question/0D50X00009ce0vWSAQ/nucleoh743zi-board-and-printf-swo-not-working

Same problem without Keil is described here:

https://community.st.com/s/question/0D53W00000bebkzSAA/nucleoh723zg-itm-printf-swv-problems

I already used ITM printf on an STM32H743 processor with Keil in another project without a problem!

Regards Jonny

void SWD_Init(void)
{
  *(__IO uint32_t*)(0x5C001004) |= 0x00700000; // DBGMCU_CR D3DBGCKEN D1DBGCKEN TRACECLKEN
 
  //UNLOCK FUNNEL
  *(__IO uint32_t*)(0x5C004FB0) = 0xC5ACCE55; // SWTF_LAR
  *(__IO uint32_t*)(0x5C003FB0) = 0xC5ACCE55; // SWO_LAR
 
  //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
 
  //SWO selected pin protocol register
   *(__IO uint32_t*)(0x5C0030F0) = 0x00000002; // SWO_SPPR
 
  //Enable ITM input of SWO trace funnel
   *(__IO uint32_t*)(0x5C004000) |= 0x00000001; // SWFT_CTRL
 
  //RCC_AHB4ENR enable GPIOB clock
   *(__IO uint32_t*)(0x580244E0) |= 0x00000002;
 
  // Configure GPIOB pin 3 as AF
   *(__IO uint32_t*)(0x58020400) = (*(__IO uint32_t*)(0x58020400) & 0xffffff3f) | 0x00000080;
 
  // Configure GPIOB pin 3 Speed
   *(__IO uint32_t*)(0x58020408) |= 0x00000080;
 
  // Force AF0 for GPIOB pin 3
   *(__IO uint32_t*)(0x58020420) &= 0xFFFF0FFF;
}

9 REPLIES 9
PTiha
Senior

Hi!

I am struggling with the same problem!

I posted about it 1 week ago, but no ST employees responded to it.

I also performed tests with NUCLEO-H743ZI2 board and NUCLEO-H723ZG board.

The STM32H743 works as expected. With STM32H723, an evaluable SWO could not be obtained in any way.

You can read my experience at the following two links:

https://community.st.com/s/question/0D53W00000bebkzSAA/nucleoh723zg-itm-printf-swv-problems

https://community.st.com/s/question/0D53W00000cxKOQSA2/sworelated-differences-between-stm32h723zg-and-stm32h743zi

JSchu.5
Associate II

Today I used my oszilloscope to measure the frequency of the SWO signal (Resistor on SB32). I followed the guide https://www.keil.com/appnotes/files/apnt_297_v102.pdf on page 4. I discovered that the signal was running at 1MHz not at 2MHz as expected. I seams that the SWO interface runs with half core frequency. I adapted the SWD Init and now it works as expected.

Edit:

The reference manual says:

0693W000008wRCqQAM.pngSo now I wanted to know where the trace clock is defined in the clock tree.

First I found this on the segger homepage:

https://www.segger.com/products/debug-probes/j-trace/technology/setting-up-trace/

"The trace clock speed (TRACECLK) is on most microcontrollers directly dependent on the CPU clock speed and is usually half of the CPU clock speed."

Then I discovered this in the STM32H723 reference manual page 3088

0693W000008wUAOQA2.pngThen I looked into the clock tree in CubeMX and discovered:

0693W000008wUAsQAM.png 

Then I compared the result with the STM32H743 clock tree of my other project:

0693W000008wUBMQA2.png 

So now I understand why my code modification is working. Maybe it is better to modify the SWD_Init code to use the DIVR1 value instead of the magic divider 2.

void SWD_Init(void)
    {
      *(__IO uint32_t*)(0x5C001004) |= 0x00700000; // DBGMCU_CR D3DBGCKEN D1DBGCKEN TRACECLKEN
     
      //UNLOCK FUNNEL
      *(__IO uint32_t*)(0x5C004FB0) = 0xC5ACCE55; // SWTF_LAR
      *(__IO uint32_t*)(0x5C003FB0) = 0xC5ACCE55; // SWO_LAR
     
      //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 / 2 / 2000000) - 1); // SWO_CODR
     
      //SWO selected pin protocol register
       *(__IO uint32_t*)(0x5C0030F0) = 0x00000002; // SWO_SPPR
     
      //Enable ITM input of SWO trace funnel
       *(__IO uint32_t*)(0x5C004000) |= 0x00000001; // SWFT_CTRL
     
      //RCC_AHB4ENR enable GPIOB clock
       *(__IO uint32_t*)(0x580244E0) |= 0x00000002;
     
      // Configure GPIOB pin 3 as AF
       *(__IO uint32_t*)(0x58020400) = (*(__IO uint32_t*)(0x58020400) & 0xffffff3f) | 0x00000080;
     
      // Configure GPIOB pin 3 Speed
       *(__IO uint32_t*)(0x58020408) |= 0x00000080;
     
      // Force AF0 for GPIOB pin 3
       *(__IO uint32_t*)(0x58020420) &= 0xFFFF0FFF;
    }

The baud rate needs to match with respect to the SWO clock coming from the ST-LINK side, usually 2 MHz on the older V2 models, and perhaps 12 or 15 MHz on the newer V3 (or whatever you've ACTUALLY set it too), and the Core side clock which you're dividing down.

You probably shouldn't need the code we were using 3 years ago, because a lot of issues/bugs got fixed with respect to H7 and dual-core functionality.

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

I agree but that wasn't the problem here. I configured Keil for 2MHz clock and did the same in my inital SWD_Init(). But I measured 1MHz instead of 2MHz. Then I adapted the prescaler in SWD_Init() by half and everythink worked. Now I'm wondering why.

I tested configuring the GPIO pin only but that din't work for me. It only works with the SWD_Init() code.

PTiha
Senior

@JSchu.5: It seems that only the divider needs to be set correctly. I commented out all other register changes from SWD_Init, and SWV still works.

0693W000008wS8GQAU.png

@PTiha​ so half clock frequency is working for you as well?

Yes, it works!

PTiha
Senior

I also reported the problem on the SEGGER forum, I got the following answer:

"Thank you for your inquiry.

I looked into this.

For the STM32H72xx and H73xx devices, we do not set some critical registers when SWO is active,

but we do so on STM32H74, etc.

This is why it is working on your H74 but not on the STM32H723ZG.

A fix will be part of the next patched release planned for Friday, this week."

PTiha
Senior

Does anyone have any new information about the SWO speed / divider anomaly?

SEGGER promises a J-Link patch for the next two weeks.

Where can I find accurate information about the changes affecting STM32H723?