Skip to main content
Visitor II
September 20, 2020
Solved

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

  • September 20, 2020
  • 3 replies
  • 11002 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?

    3 replies

    Graduate II
    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.

    bcAuthor
    Visitor 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.

    Graduate II
    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​

    Explorer 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:

    bcAuthor
    Visitor 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.

    Nikita91Answer
    Explorer 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?

    bcAuthor
    Visitor 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!