Skip to main content
turboscrew
Senior III
December 4, 2018
Question

Core peripherals?

  • December 4, 2018
  • 4 replies
  • 1097 views

Where, in the documentation of STM32 devices, can I find out which optional core peripherals are implemented?

This topic has been closed for replies.

4 replies

Tesla DeLorean
Guru
December 4, 2018

Like the ITM and DWT? Some of that's in the CM4 ROM TABLES

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Tesla DeLorean
Guru
December 4, 2018
Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
turboscrew
Senior III
December 4, 2018

But usually not in documents?

For reading the ROM tables, you need the devices and a debugger or program that dumps the info.

I did that once (the program) for an A7, but don't remember how it was done. I remember it was somewhat complicated...

Tesla DeLorean
Guru
December 4, 2018

Likely to have some coverage in the Programming Manual or Reference Manual, personally find a lot of this stuff to be duplicative. You also run into issues where there's a line between ARM's public docs and NDA coverage for the IP.

The ROM TABLEs should be visible, and frequently in the DBGMCU space. Should be able to dump the 32-bit words to a terminal, or walk the elements and determine addresses of sub-units with varying levels of public disclosure. Last time I pulled this stuff apart was to auto-configure the SWV baud rates on CM4 and CM7 parts, and the H7.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Tesla DeLorean
Guru
December 4, 2018

Some of the voodoo here is explained in the H7 RM, other stuff and details culled from ARM and other sources. I'm sure ARM has docs they share specifically with debugger vendors, and a walk through of OpenOCD and scripts might also shed some light on internal mechanics.

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

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
turboscrew
Senior III
December 5, 2018

I guess ARM usually has documentation. It's just that some features of the cores are optional, and I'm interested in which optional features are implemented. The "how" is another thing, but usually Arm defines that.

turboscrew
Senior III
December 5, 2018

This is how I did it in RPi2B (rpi_stub):

	asm volatile (
			"mrc p14, 0, %[retreg], c1, c0, 0 @ get DBGDRAR\n\t"
			"dsb\n\t"
			: [retreg] "=r" (tmp1)::
	);
...
	tmp1 &= 0xfffff000; // masked DBGDRAR (ROM table address)
 rom_addr = tmp1;
...
	tmp1 = rom_addr; // masked DBGDRAR (ROM table address)
	ptmp1 = (uint32_t *)tmp1; // ptmp1: pointer to component entries
	for (i=0; i<(0xf00/4); i++)
	{
		tmp2 = *(ptmp1++);
		asm volatile("dsb\n\t");
		// print component entry
		serial_raw_puts("\r\ncomp: ");
		util_word_to_hex(scratchpad, i);
		serial_raw_puts(scratchpad);
		serial_raw_puts(" : ");
		util_word_to_hex(scratchpad, tmp2);
		serial_raw_puts(scratchpad);
		if (tmp2 == 0) break; // end of component entries
 
		tmp2 &= 0xfffff000; // masked component offset
 
		ptmp2 = (uint32_t *)(tmp1 + tmp2);
		tmp3 = *ptmp2;
		serial_raw_puts("\r\nDBGDIDR: ");
		util_word_to_hex(scratchpad, tmp3);
		serial_raw_puts(scratchpad);
 
		ptmp2 = (uint32_t *)(tmp1 + tmp2 + 0xff4);
		tmp3 = ((*ptmp2) & 0xff);
		serial_raw_puts("\r\nCIDR1: ");
		util_word_to_hex(scratchpad, tmp3);
		serial_raw_puts(scratchpad);
 
		ptmp2 = (uint32_t *)(tmp1 + tmp2 + 0xfd0);
		tmp3 = ((*ptmp2) & 0xff);
		serial_raw_puts("\r\nPIDR5: ");
		util_word_to_hex(scratchpad, tmp3);
		serial_raw_puts(scratchpad);
 
		ptmp2 = (uint32_t *)(tmp1 + tmp2 + 0xfcc);
		tmp3 = ((*ptmp2) & 0xff);
		serial_raw_puts("\r\nDEVTYPE: ");
		util_word_to_hex(scratchpad, tmp3);
		serial_raw_puts(scratchpad);
		if ((tmp3 & 0xf) == 5)
		{
			serial_raw_puts(" (debug)");
		}
		else if ((tmp3 & 0xf) == 6)
		{
			serial_raw_puts(" (perfmon)");
		}
 
		ptmp2 = (uint32_t *)(tmp1 + tmp2 + 0xfe0);
		tmp3 = ((*(ptmp2++)) & 0xff);
		asm volatile("dsb\n\t");
		tmp3 |= (((*(ptmp2++)) & 0xff) << 8);
		asm volatile("dsb\n\t");
		tmp3 |= (((*(ptmp2++)) & 0xff) << 16);
		asm volatile("dsb\n\t");
		tmp3 |= (((*(ptmp2++)) & 0xff) << 24);
		asm volatile("dsb\n\t");
		serial_raw_puts("\r\nPIDR: ");
		util_word_to_hex(scratchpad, tmp3);
		serial_raw_puts(scratchpad);
	}
 serial_raw_puts("\r\n");