cancel
Showing results for 
Search instead for 
Did you mean: 

32F417: How to use SWV ITM SWO debug output, without Cube IDE or even a debugger?

PHolt.1
Senior III

I have overall found this feature to be very unreliable, for reasons unknown. The data comes out OK from PB3 and goes all the way to the STLINK V3, at the expected speed, 1MHz, but Cube IDE displays nothing. I have this across a number of development units. Sometimes it works and then stops...

Anyway, digging into this, it looks like the entire trace macrocell is configured via the debugger when (or before) reset is released from the target. That is why none of the STM example code sets up any of this stuff. I also managed, years ago, to get SWV working not with Cube IDE but with the STM32 STLINK Utility, which presumably does the same via-debugger config tricks.

Also just because you see 1MHz stuff on the scope doesn't mean that it is in the right format for Cube IDE to decode it.

So I went looking for how to get this stuff configured in software in the target. Obviously any such config will override the Cube/debugger config so you will have to make sure Cube IDE's config matches exactly if you still want that to work. And after a lot of work I found the following, and wonder whether it is complete:

1) Set up PB3 to be an output, probably fast mode, and enable portb clock.

2) Set up the macrocell. I found this on this ST forum

/*
	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 ;
	}
}

 What I don't get however is the comment "ITM/SWO works only if enabled from debugger.". What is this about? There may not be a debugger!

The actual output function is the usual ST one:

// Copy of the one in core_cm4.h
static inline void ITM_SendChar (uint32_t ch)
{
  if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) &&      /* ITM enabled */
      ((ITM->TER & 1UL               ) != 0UL)   )     /* ITM Port #0 enabled */
  {
    while (ITM->PORT[0U].u32 == 0UL)
    {
      __NOP();
    }
    ITM->PORT[0U].u8 = (uint8_t)ch;
  }
  return;
}

 

4 REPLIES 4
Andrew Neil
Super User

@PHolt.1 wrote:

I found this on this ST forum


Please give a link to where you found it.

 


@PHolt.1 wrote:

What I don't get however is the comment "ITM/SWO works only if enabled from debugger.". What is this about?

Some debug features are only accessible via a debugger - the CPU has no access.

See also DHCSR in Cortex-M0.

PS:

ARM document accessible registers here.

ARM's SWO documentation here.

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
PHolt.1
Senior III

It is in this thread

https://community.st.com/t5/stm32-mcus-boards-and-hardware/how-to-enable-swo-with-st-link-utility-on-stm32f407g-disc1/td-p/228896

Re with-debugger-only operation, I recall reading that the SWO output can be used without a debugger. It seems to be just a UART. The above link and the code there suggests that is the case, otherwise who would bother?

You can also look here

https://gist.github.com/mofosyne/178ad947fdff0f357eb0e03a42bcef5c

which contains similar stuff.


@PHolt.1 wrote:

It seems to be just a UART.

AIUI, one of the supported SWO protocols is UART:

https://community.st.com/t5/stm32-mcus-boards-and-hardware/uart-signal-on-swo-pin-from-st-link-v2-3/m-p/742817/highlight/true#M22588

 

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
PHolt.1
Senior III

Yes; it supports various encodings including Manchester, but AFAICT the 32F4 to STLINK V3 to Cube IDE interface is just a standard NRZ UART.

Presumably one doesn't have (up to) 12MHz NRZ going back to the PC via USB :) so the reception must be implemented by the STM CPU in the debugger (32F723 in the little one I am looking at) which packages the data and buffers it for the PC host to retrieve it over USB.

Looking at it on a scope, it looks like a standard microcontroller UART i.e. normally high, with a start bit going low. But I can't be sure.

It would be interesting if it could be used as a standalone output. I cannot find details of these registers anywhere e.g.

TPI->FFCR	= 0x00000100u ;