Skip to main content
bc_it
Associate II
September 20, 2020
Solved

How to enable SWO with ST-Link Utility on STM32F407G-DISC1

  • September 20, 2020
  • 8 replies
  • 11116 views

I'm working with the STM32-base template for F4 located here:

https://github.com/STM32-base/STM32-base-F4-template

To compile with gcc toolchain and loading the binary with STLink Utility. The binaries work fine on the board, but I cannot figure out how to enable Serial Wire Output (SWO) in the STLink Utility interface or get a serial output to show up. I've added IE:

#include <stdio.h> // up top

printf("hello world"); // in main()

ITM_SendChar('s'); // alternatively, in main()

All of which seems to compile fine, I can get a blinky LED On the port fine, but no serial output.

STLink Utility is v. 4.5.0.0

This topic has been closed for replies.
Best answer by Nikita91

The system core clock value is available in 'SystemCoreClock' variable (must be 168M for you),

The ITM_SendChar function use stimulus 0, so:

swoInit (0x1, SystemCoreClock , 2000000);

The bItmAvailable variable must be initialized to 0, and it is set to 1 only if the SWO init succeed.

To printf to the SWO I think it is necessary to modify the _write() function in syscall.c

The "SWD Frequency = 4,0 MHz." frequency is related to debug communication (SWD-SWC pins), not to SWO.

Your template mail.c file doesn'i initialize anything. Dou you have a function like SystemClock_Config() to initialize the MCU clocks ?

Does the LED blink rate match what you want?

8 replies

Tesla DeLorean
Guru
September 20, 2020

Make sure the SWO/PB3 solder bridge is made.

Ensure you tell the tool what speed the core is actually running at.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
bc_it
bc_itAuthor
Associate II
September 21, 2020

Thank you clive. In the STM32F407G-DISC1 manual (UM1472, page 27), the corresponding solder bridge seems to be SB12, is that right? This is soldered on the back of the board (there seems to be a small smd resistor across it, I did not solder this myself).

How can I determine the core speed? I see a file 'system_stm32f4xx.c' in the project with:

#if !defined (HSE_VALUE) 
 #define HSE_VALUE ((uint32_t)25000000) /*!< Default value of the External oscillator in Hz */
#endif /* HSE_VALUE */
 
#if !defined (HSI_VALUE)
 #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */

Is it potentially one of these?

Thanks again.

Tesla DeLorean
Guru
September 21, 2020

Typically depends on the clock source you are using, most often PLL at 168 MHz

HSE_VALUE here should be 8 MHz, check also your PLL divider in main.c, and setting for HSE_VALUE in stm32f4xx_hal_conf.h​

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Nikita91
Lead II
September 21, 2020

To ena

//-------------------------------------------------------------------------------------------------
/*
	Initialize the SWO trace port for debug message printing
	portMask : Stimulus bit mask to be configured
	cpuCoreFreqHz : CPU core clock frequency in Hz
	baudrate : SWO frequency in Hz
*/
 
void swoInit (uint32_t portMask, uint32_t cpuCoreFreqHz, uint32_t baudrate)
{
	uint32_t SWOPrescaler = (cpuCoreFreqHz / baudrate) - 1u ; // baudrate in Hz, note that cpuCoreFreqHz is expected to match the CPU core clock
 
	CoreDebug->DEMCR = CoreDebug_DEMCR_TRCENA_Msk; 		// Debug Exception and Monitor Control Register (DEMCR): enable trace in core debug
	DBGMCU->CR	= 0x00000027u ;							// DBGMCU_CR : TRACE_IOEN DBG_STANDBY DBG_STOP 	DBG_SLEEP
	TPI->SPPR	= 0x00000002u ;							// Selected PIN Protocol Register: Select which protocol to use for trace output (2: SWO)
	TPI->ACPR	= SWOPrescaler ;						// Async Clock Prescaler Register: Scale the baud rate of the asynchronous output
	ITM->LAR	= 0xC5ACCE55u ;							// ITM Lock Access Register: C5ACCE55 enables more write access to Control Register 0xE00 :: 0xFFC
	ITM->TCR	= 0x0001000Du ;							// ITM Trace Control Register
	ITM->TPR	= ITM_TPR_PRIVMASK_Msk ;				// ITM Trace Privilege Register: All stimulus ports
	ITM->TER	= portMask ;							// ITM Trace Enable Register: Enabled tracing on stimulus ports. One bit per stimulus port.
	DWT->CTRL	= 0x400003FEu ;							// Data Watchpoint and Trace Register
	TPI->FFCR	= 0x00000100u ;							// Formatter and Flush Control Register
 
	// ITM/SWO works only if enabled from debugger.
	// If ITM stimulus 0 is not free, don't try to send data to SWO
	if (ITM->PORT [0].u8 == 1)
	{
		bItmAvailable = 1 ;
	}
}

ble SWO on F4:

bc_it
bc_itAuthor
Associate II
September 22, 2020

Thanks Nikita! I put this in main.c and called it as swoInit(0xFFFFFFFF, 168000000, 2000000); I also had to set bItmAvailable (=1) since it doesn't appear in the code anywhere. Are these arguments correct, and if not how do I determine what they should be? In STLink Utility, the SWV window shows "SWV Frequency: 2000kHz". But also, when I connect to the board, I get a console message "SWD Frequency = 4,0 MHz."

Calling as above does not allow me to print anything to the SWO console with printf.

Thanks again.

Nikita91
Nikita91Best answer
Lead II
September 22, 2020

The system core clock value is available in 'SystemCoreClock' variable (must be 168M for you),

The ITM_SendChar function use stimulus 0, so:

swoInit (0x1, SystemCoreClock , 2000000);

The bItmAvailable variable must be initialized to 0, and it is set to 1 only if the SWO init succeed.

To printf to the SWO I think it is necessary to modify the _write() function in syscall.c

The "SWD Frequency = 4,0 MHz." frequency is related to debug communication (SWD-SWC pins), not to SWO.

Your template mail.c file doesn'i initialize anything. Dou you have a function like SystemClock_Config() to initialize the MCU clocks ?

Does the LED blink rate match what you want?

bc_it
bc_itAuthor
Associate II
September 24, 2020

Aha! Yes, this gets it working for ITM_SendChar(). The system clock I set in STLink Utiliy for SWV was 168MHz. I'll write a more full reply tomorrow when I can more fully go through the points in your post, but it's great to have some character output finally. Thank you!