Update 2020-06-14: Added HK32
Hello there. This is a follow up on the comparison for the *32F103 parts. We’ve got the STM32F103C8T6, GD32F103C8T6, HK32F103CBT6, 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).
For the HK32, The JP106-used bit is not set. This means, the values for the vendor are not JEDEC assigned IDs. According the the ARM Debug Specs, in this case a legacy ID is used. The ID should contain an ASCII character to indicate a manufacturer. We see ID 85, which in the ASCII table is in ‘U’. Furthermore, we see the Continuation filled, but when interpreting the ID as a legacy ID, this field should be 0. Therefore, these values appear not to be according to specification, but these values give enough information to distinguish the part.
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 HK32 : Cortex-M3 r2p1 V:0 CONT: 5 ID: 85 PART: 29B 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.
See github for detection code 2020-06-14: Detection works, but on my HK32 board, the USB does not enumerate. I will have to investigate whether this is a incompatibility or an issue with my board.
Hi Andre, do you know what the output of the HK32F103 would be in the list above? And is it possible to discern the HK32 from the other uC‘s in the list? Best regards, Joerg
I haven’t tested the HK32 yet. I was thinking about to do so this weekend.
Unfortunately, it seems something went wrong with the board I prepared. Last week I soldered a HK32 chip to a new board ( https://github.com/a-v-s/pcb_stm32XxxxCx_board ).
Everything seemed to be soldered fine, but when I tried to hook it up today, I connected a debugger, I connected a USB power cable, and I was about to read out the JTAG chain, I saw some smoke in the corner of my eye. Oops. There is no smell though.
Upon measurement, it seems there is some short circuit ( About 2 Ohm between VCC and GND ). I will investigate, but I am afraid I fried the microcontroller somehow, as it looks like there is a small hole where the HK logo is.
I‘m sorry for the bad luck.
There have been HK32F103 relabeled/faked as STM32F103, so it would be really interesting, what parse_romtable() would find (https://github.com/a-v-s/ucdev/blob/master/demos/cortex_romtable/stm32f1/main.c#L122).
I got a boaed with only the HK32 and JTAG connector soldered on it. Enough to run part 2 of the test. So far that works. I can also read the ROMTABLE from OpenOCD. This shows me for the first entry:
Component base address 0xe00ff000
Peripheral ID 0x050005529b
Designer ASCII code 0x55,
Part is 0x29b, Unrecognized
Component class is 0x1, ROM table
MEMTYPE system memory present on bus
Looks like an invalid designer value, but I guess this means I will be able to tell it apart from the other clones I’ve discussed so far.
I’ve updated the demo on github to detect the HK32. I have tested this in the bare state my PCB is now. (So USB part is not tested on the HK32 chip, only the ROMTABLE part is tested)
Thanks, Andre!!
I’ve finished by board. When running with my USB code, it does not enumerate. I’ll still have to see whether this is an incompatibility with the HK32 or an issue with my board.