Hello there. This is a follow up on the comparison for the *32F103 parts. We’ve got the STM32F103C8T6, GD32F103C8T6, CS32F103C8T6 and APM32F103C8T6. As seen in part 2, there are some differences in how they identify themselves to the debugger. Now I’ll have a look at the ROMTABLE. I can query this information from within my code as well.

Surprisingly, there are some differences in the results I get from the debugger versus from code. As discussed in the ROMTABLE post, the STMicroeceltronics and the GigaDevice part identify themselves as such when looking at the PeripheralID values in the ROMTABLE.

The ApexMic and CKS parts gave different results when scanning the JTAG chain. Now, querying the ROMTABLE PID from code gives different results. BOTH the APM and CS part answer with bank 5 entry 59. Looking that one up gives me “ARM Ltd.”. Well…. it uses an ARM core, that’s right, but are you supposed to identify the core or the part which uses the core? Speaking about the core, the clones are of a newer revision of the Cortex M3 core. We can see that by looking at the CPUID. On an ARM core, we can find the CPUID in the System Control Space (SCS).

BEWARE: The revision is encoded in a rnpn scheme where r stands for revision and p for patch has a naming mismatch where with the CPUID register. CPUID Variant is Revision, CPUID Revision is Patch. This is confusing, and one may easily mix them up as they both use the word revision for a different field.

There is some more information in the Peripheral IDs such as a Part Number and a Revision. As specified in the ARMv7 TRM (ID120114) Appendix D1.

STM32 : Cortex-M3 r1p1  V:1 CONT:  0 ID: 32 PART: 410 REV:  0 
GD32  : Cortex-M3 r2p1  V:1 CONT:  7 ID: 81 PART: 76F REV:  0 
CS32  : Cortex-M3 r2p1  V:1 CONT:  4 ID: 59 PART: 4C3 REV:  0 
APM32 : Cortex-M3 r2p1  V:1 CONT:  4 ID: 59 PART: 4C3 REV:  0 

So we see, the original STM32F103 is a Cortex-M3 r1p1, while the others are r2p1. This indicates a later patch level. As those microcontrollers are designed at a later time, this makes perfect sense. When one goes to ARM today to buy a Cortex-M3 license, one obtains the current revision. As the STM32F1 is one of the first Cortex M3 designs, it makes sense they’ve got an earlier revision of the core. The differences between the revisions can be looked up in the Cortex M3 Technical Reference Manual,

When looking at the values for part number, we notice that the STM32 has a part number of 0x410. This is the same value we’d expect when reading the DBGMCU_IDCODE register. But this time we don’t suffer from Errata 2.3: this value can be read from user code without debugger attached. When we look at the GigaDevice, we see a whole different part number. These part numbers are assigned by the manufacturer. Both the ApexMic and CKS part report manufacturer ARM Ltd., part number 4C3, which corresponds with Cortex-M3 ROM.

So far, I’ve been able to tell the STM and GD parts apart from the CS and APM, however, from code I haven’t yet found a way to distinguish the CS and APM, however, from a JTAG debugger, I could tell the difference from the debugger. Let’s have a look over there. The ROMTABLE contains some more information then just the Peripheral ID. It is a table after all, and there is some data in that table. I’ll have OpenOCD read the ROMTABLE for me. To dump all the output here would be way too long. But one thing, it shows all the components to be expected,

  • Cortex-M3 ROM (ROM Table)
  • Cortex-M3 SCS (System Control Space)
  • Cortex-M3 DWT (Data Watchpoint and Trace)
  • Cortex-M3 FPB (Flash Patch and Breakpoint)
  • Cortex-M3 ITM (Instrumentation Trace Module)
  • Cortex-M3 TPIU (Trace Port Interface Unit)

The first entry, “Cortex-M3 ROM (ROM Table)” shows up like this on the CS and APM, On the STM and GD we get “Unrecognized” as they have STM or GD part numbers

Interestingly on the CS32F103C8T6, there is an additional entry present, which is absent on the others: Cortex-M3 ETM (Embedded Trace).
Whether an actual ETM is present, I don’t know, but I know it won’t be usable, as the pins defined for ETM are only available in 100 pin packages, and the component I’m looking at is in an 48 pin package. Nevertheless, this gives a way to tell them apart. Since the ROMTABLE is accessible from code, I can write a detection code that will be able to tell at least the STM32F103C8T6, GD32F103C8T6, CS32F103C8T6 and APM32F103C8T6 apart.