cancel
Showing results for 
Search instead for 
Did you mean: 

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

bc
Associate II

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

1 ACCEPTED SOLUTION

Accepted Solutions
Nikita91
Lead II

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?

View solution in original post

8 REPLIES 8

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 Up vote any posts that you find helpful, it shows what's working..

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.

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 Up vote any posts that you find helpful, it shows what's working..
Nikita91
Lead II

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:

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.

bc
Associate II

Thanks Clive. Where do I find the PLL clock source? Setting HSE_VALUE to 8MHz here and System Clock to 168MHz doesn't show anything on the SWO viewer in STLink Utility. The 'main.c' file is here:

https://github.com/STM32-base/STM32-base-F4-template/blob/master/src/main.c

I don't see anything in there that looks like a PLL divider.

There isn't a file 'stm32f4xx_hal_conf.h' in any of the linked files; there is a file 'stm32f4xx_hal_conf_template.h' here:

https://github.com/STM32-base/STM32-base-STM32Cube/blob/master/HAL/STM32F4xx/inc/stm32f4xx_hal_conf_template.h

Any idea what/if I need to change in any of these?

Thanks again

Nikita91
Lead II

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?

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!