Update 2020-06-13: Added the HK32, updated stlink-gui/st-flash: it works with CKS32 now.
Welcome back to my 32F103 Comparison. Let’s recap. The STM32F103C8T6 is a popular microcontroller by STMicroelectronics. Various Chinese manufacturers are producing parts in the same naming scheme, eg. APM32F103C8T6, BLM32F103C8T6, CS32F103C8T6, GD32F103C8T6 and MM32F103C8T6. What does this mean? There are parts, such as the famous 555 timer, you can get from many manufacturers and you can expect to get a compatible part. The same holds for the 7400 series and components such as opamps. However, there are edge cases where an equivalent part from another manufacturer won’t work. See EEVblog #1057 – µCurrent Murphy for issues related from a same part from a different manufacturer.
When we enter the world of microcontrollers, this does not have to apply. Even though a similar looking naming scheme might suggest compatibility, this is not always the case.
So far, the ordered MCUs are at least pin-compatible. I’ve soldered them to boards, and I’ll attach a debugger and see what we’ve got. What will I be looking at? First of all, these chips speak both SWD and JTAG. I’ll connect to them over JTAG, to see how they identify themselves in their ROMTABLE.
Furthermore, I’ll see if I can attach a debugger, using OpenOCD configured for an STM part, and I’ll see what QStlink2 makes of it.
JTAG Identification
For this test, I’ll hook op a SEGGER J-Link Edu Mini to the board, and run
openocd -f "interface/jlink.cfg" -c "transport select jtag; adapter_khz 4000;"
for each board. This will cause openocd to connect over the JTAG protocol and autoconfigure the chain. This configure will not be any good for actual debugging, but will show what is connected.
STM32F103C8T6
Info : JTAG tap: auto0.tap tap/device found: 0x3ba00477 (mfg: 0x23b (ARM Ltd.), part: 0xba00, ver: 0x3) Info : JTAG tap: auto1.tap tap/device found: 0x16410041 (mfg: 0x020 (STMicroelectronics), part: 0x6410, ver: 0x1)
When we look at the original STMicroelectronics part, we see OpenOCD has autoconfigured the chain, and sees two taps. We see a tap where the manufacturer is ARM (The Cortex-M3 core) and we see a TAP where the manufacturer is STMicroelectronics. This is what is expected.
GD32F101CBT6
Info : JTAG tap: auto0.tap tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd.), part: 0xba00, ver: 0x4) Info : JTAG tap: auto1.tap tap/device found: 0x790007a3 (mfg: 0x3d1 (GigaDevice Semiconductor (Beijing)), part: 0x9000, ver: 0x7)
When we look at a GigaDevice part (This is actually an F101 rather then an F103). Again we see two taps, one by ARM and one by GigaDevice. This is what it should look like. A part that identifies itself correctly. One thing to notice is the ARM part has another version number. I believe this refers to the revision of the debugger interface, I’ll come back to this later.
APM32F103C8T6
Info : JTAG tap: auto0.tap tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd.), part: 0xba00, ver: 0x4) Info : JTAG tap: auto1.tap tap/device found: 0x16410001 (mfg: 0x000 (<invalid>), part: 0x6410, ver: 0x1)
At the ApexMic part, we get a report of an invalid manufacturer. At least it doesn’t lie.
BLM32F103C8T6
Info : JTAG tap: auto0.tap tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd.), part: 0xba00, ver: 0x4)
BetterLife only shows the ARM TAP. So, it only shows the ARM Debugger interface, giving no clue about the device itself.
CS32F103C8T6
Info : JTAG tap: auto0.tap tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd.), part: 0xba00, ver: 0x4) Info : JTAG tap: auto1.tap tap/device found: 0x16410041 (mfg: 0x020 (STMicroelectronics), part: 0x6410, ver: 0x1)
Looking at the CS32, we see something dirty! This microcontroller pretends to be a STMicroelectronics. Nasty!
HK32F103CBT6
Info : JTAG tap: auto0.tap tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd.), part: 0xba00, ver: 0x4)
Hangshun only shows the ARM TAP.
MM32F103C8T6
Info : JTAG tap: auto0.tap tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd.), part: 0xba00, ver: 0x4)
MindMotion only shows the ARM TAP.
The version of the part
In the output we see the debugger interface, Manufacturer 0x23b (ARM Ltd.), Part 0xba00, with either version 3 or 4. I’m not entirely sure about this part, when I look through the specifications.
In the CoreSight SoC Technical Reference Manual – CoreSight Design Kits is mentioned as the JTAG-AP part number, however, it mentions the version should be 5. In the CoreSight SoC Technical Reference Manual – CoreSight-Soc400 it mentions again 0xba00 as the part number for JTAG-AP, with version 4. Version 3 is mentioned as the version for the SWD-AP, but that has part number 0xBA02. So I’m not entirely sure what is going on. Also, I guess I don’t have a complete understanding about which Technical Reference Manual is applicable. I mean, I know I’m dealing with a Cortex-M3 microcontroller. I believe CoreSight is the debugger interface, but what is SoC-400 or SoC-600? I believe DAP-Light is used on Cortex M0, but what is used on the orther Cortex-M series? I don’t know at this moment.
However, apart from looking the version number up in the documentation, are there any relevant differences between those versions that could have implications while using or debugging the microcontroller? There are other reasons why this might be relevant. When browsing the internet, there are a number of questions regarding these numbers. When using OpenOCD, this might result in error messages like
Warn : UNEXPECTED idcode: 0x2ba01477 Error: expected 1 of 1: 0x1ba01477
or
Warn : JTAG tap: stm32f1x.cpu UNEXPECTED: 0x4ba00477 (mfg: 0x23b (ARM Ltd.), part: 0xba00, ver: 0x4) Error: JTAG tap: stm32f1x.cpu expected 1 of 1: 0x3ba00477 (mfg: 0x23b (ARM Ltd.), part: 0xba00, ver: 0x3)
The first one appears to only show up when connecting using an ST-Link debugger connecting over SWD, and does not show up on a J-Link debugger connecting over SWD. The second one shows up on a J-Link debugger connecting over JTAG.
This solution will work, but requires changing configuration files while changing chips
#jtag scan chain if { [info exists CPUTAPID] } { set _CPUTAPID $CPUTAPID } else { if { [using_jtag] } { # Replace 0x3ba00477 with 0x4ba00477 #set _CPUTAPID 0x3ba00477 set _CPUTAPID 0x4ba00477 } { # Replace 0x1ba00477 with 0x2ba00477 #set _CPUTAPID 0x1ba01477 set _CPUTAPID 0x2ba01477 } }
In theory there should be a way to ignore the version all together, using the -ignore-version
option. However, the ST-Link HLA driver ignores this and still gives the error.
# Adding -ignore-version at the end swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID -ignore-version
This fixes the problem when connecting over JTAG using an J-Link. For some reason, when connecting over SWD using the J-Link, the version was already being ignored. I guess these are caused by differences between the normal JTAG/SWD implementation and the High Level Architecture used by the ST-Link.
Compatibility with existing tools
I have tested whether these MCUs work with existing tools targetting the STM32. There are many tools out there, I have to make a selection which ones to test. Personaly, I usually use only OpenOCD, for both flashing and debugging. I have tested dedicated flash tools st-flash / stlink-gui and qstlink2. All of these tools use an ST-Link debugger. Furthermore, I have tested OpenOCD as a debugger, which supports the ST-Link and many other debuggers such as the J-Link. I’ve also tested JLinkExe (aka J-Link Commander), a commercial tool by SEGGER, which works with their J-Link debuggers.
APM32F103C8T6
Flashing:
qstlink2 | FAIL |
Connects fine, hangs on flashing | |
stlink-gui / st-flash | FAIL |
Erases fine, writing fails (unknown coreid, not sure what flash loader to use, aborting!) | |
OpenOCD | SUCCESS |
Works fine with the adjustments in the condig file described above | |
JLinkExe | TBD |
J-Link has no specific support for this part. TODO: Selecting the ST part probably works, verify this |
BLM32F103C8T6
qstlink2 | FAIL |
Error: Did not find chipID! | |
stlink-gui / st-flash | FAIL |
Unknown Chip ID | |
OpenOCD | FAIL |
Cannot identify target as a STM32 family. | |
JLinkExe | TBD |
J-Link has no specific support for this part. TODO: Probably won’t work, |
CS32F103C8T6
qstlink2 | FAIL |
Connects fine, hangs on flashing | |
stlink-gui / st-flash | |
Update 2020-06-13: It works noq. Probably fixed in a later version then I used back in the days. I didn’t note the version back then, but today the version is v1.6.0 |
|
OpenOCD | SUCCESS |
Works fine with the adjustments in the condig file described above | |
JLinkExe | TBD |
J-Link has no specific support for this part. TODO: Selecting the ST part probably works, verify this |
GD32F103C8T6
qstlink2 | SUCCESS |
Connects fine, flashes fine | |
stlink-gui / st-flash | SUCCESS |
Erases fine, flashes fine | |
OpenOCD | SUCCESS |
Works with original config. Even though on mass erase it times out. | |
JLinkExe | TBD |
J-Link has specific support for this part |
HK32F103CBT6
qstlink2 | FAIL |
Connects fine, hangs on flashing | |
stlink-gui / st-flash | SUCCESS |
OpenOCD | SUCCESS |
Works fine with the adjustments in the condig file described above | |
JLinkExe | TBD |
MM32F103C8T6
qstlink2 | FAIL |
Connects fine, says Unknown Device | |
stlink-gui / st-flash | FAIL |
Did not find chipID! | |
OpenOCD | FAIL |
Cannot identify target as a STM32 family. | |
JLinkExe | TBD |
J-Link has specific support for this part |
Conclusions
APM32F103C8T6
This part lacks documentation, (there is only a Chinese datasheet, which only gives a global overview, no register descriptions). The company’s website is having issues, which have been there for the past month, which is gives them poor credibility. The mcu appears to have some level of compatibility. So far, we’re able to program it using OpenOCD. Further testing will have to give some clues about code compatibility.
BLM32F103C8T6
This part is not compatible with the STM counterpart. As it lacks documentation, I’d say, it’s completely useless. I have no clue how to continue testing this part
CS32F103C8T6
This part lacks documentation, (there is only a Chinese datasheet, which only gives a global overview, no register descriptions). It is unclear who manufactures it. It appears to have some level of compatibility. Chinese sellers claim it is a ‘drop-in replacement’. So far, we’re able to program it using OpenOCD. Further testing will have to give some clues about code compatibility.
GD32F103C8T6
The GigaDevice part has been around for years. It works with existing tools. It has been discussed by various people in the past. There is a good level of code compatibility. I’ve had some experience with this part in the past, and so far I’ve not run into code-compatibility issues.
MM32F103C8T6
While this part is only pin compatible, but incompatible firmware and programming wise, it can not rely on existing flashing tools and debugging software. There is support for this part in commercial software (SEGGER J-Link), so it is possible to use this part with off-the-shelf tools. Looking at the documentation provided (I only took a quick glance), I believe it should not be hard to add support to open source tools. Is it worth it? Maybe if you need the speed (168 MHz vs 72 MHz)?
Hi,
Concerning the CSK, check: https://cksic.en.china.cn/about.html
The site http://www.cksic.com/ is down
Check the discussion on: https://www.eevblog.com/forum/microcontrollers/cheap-bluepill-very-likely-it-has-fake-stm32-right/
It points to a datasheet: https://wiki.cuvoodoo.info/lib/exe/fetch.php?media=jtag:ic_mcu_cks_cks32f103xb_en.pdf
Best regards,
Sam
If you look towards the end of the EEVBlog discussion, you’ll see a few posts by me (GromBeestje).
The site http://www.cksic.com/ loads fine here. It is all in Chinese, which I can’t read, but it seems there is no reference of the chip. I’ve been aware of that datasheet, but that doesn’t confirm China Key Systems is behind it, as anyone can copy-paste a logo into a PDF.