DIY STM32 Programmer (ST-Link/V2-1)

From Stm32World Wiki
(Redirected from DIY ST-Link V2.1)
Jump to navigation Jump to search
Original ST-Link

ST-Link devices are almost essential when developing software for the STM32 MCUs. They are relatively cheap and easily available.

They roughly fall into two different categories. ST themselves make a number of them and they all work quite well.

One thing that annoys me with the original ST-Link devices is that the programming header is unlabelled. This essentially mean that every time I use it I have to Google for the actual pinout.

Also, the ones I've got (the one in the photo to the right) are ST-Link/V2 devices.

Before diving into any further details, credits to Martin from EmbeddedBlog who went through the same as here. His project is linked under Miscellaneous Links.

Chinese knock off ST-Link/V2

There are also a lot of Chinese clones available and while they have some limitations they also work quite well.

Unfortunately these devices are also ST-Link/V2 devices, and they do not have the SWO pin on the header, so any debug trace is impossible. For flashing and normal debugging they work fine though.

In short, the ST-Link/V2.1 devices offer a few extra features:

  1. Serial Wire Trace (SWO)
  2. Virtual serial port
  3. Mass storage

All features that, while not absolutely essential, does come quite handy.

Another reason for creating my own "programmer" is that I can experiment with using a GigaDevice GD32F103, which are much easier to source at the moment.

Original ST-Link V2.1

The schematic of the original ST-Link is readily available from the various Nucleo development modules.

ST-Link V2.1 Original Schematics.png

A bit messy schematics but it'll do.

Schematics

Based on ST's original schematics, creating a version using only parts from JLCPCB's parts library was easy (and much nicer if I shall say so myself).

DIY ST-Link V2.1.svg

One thing I left out was the serial resistors of the programming header. This might very well come back and bite me in the ass but space is going to be at a premium.

The main difference hardware wise between ST-Link/V2 and ST-Link/V2-1 is the renumeration circuitry:

ST-Link-V2-1 Renumeration Circuitry.png

I think what is going on there is ensuring the D+ is pulled high through the 1.5 kOhm resistor unless the RENUM signal is forced low. The voltage divider R4/R5 and R6 are merely there to protect the transistor itself. While I do understand what they (ST) are trying to achieve, I would say they could have achieved this much simpler. IF the D+ was simply permanently pulled high by the 1.5 kOhm resistor, since it is connected to a GPIO pin, this GPIO pin could simply be briefly yanked low at MCU reset (see STM32 USB Device Renumeration).

It should be noted that firmware update at the moment does not work and this could be related to this not being implemented correctly.

As for MCU the original ST-Link/V2-1 uses an STM32F103CB (128 kB flash). Since it is well known that STM32F103C8 MCUs also have 128 kB flash this one should do nicely too. In this case however, due to the general shortage of STM32 MCUs, I went with a GigaDevice GD32 instead. It should be "compatible" enough for this purpose.

PCB

For hobby projects like this I will usually stick with double-sided PCB. But in this particular case I wanted this to fit into the aluminium "sleeve" of the Chinese knock off ST-Link devices, so space was at a premium. Also, pricing wise there's not much difference these days, so I went for a four layer PCB and kept +3.3V and GND on the two inner layers.

For SMT assembly, JLCPCB has a minimum size of 20 mm in either direction:

JLCPCB Assembly Capabilities.png

For a USB stick 20 mm is too wide, so I had to design the PCB with a breakaway part connected with mouse bites.

The final rev. a layout looks like this:

PCB Layout rev. a.png

The KiCAD 3D model:

PCB Layout rev. a - 3D model.png

Revision a

A quick order to JLCPCB and within a week I had my first "samples".

I had to solder the USB connector by hand and it turned out that I was either out of IDC connectors (or couldn't be bothered to search long enough to dig them out of a box), so I used a simple dual-row standard 100 mil header.

DIY ST-Link w. USB connector and header.jpg DIY St-Link Hooked up.jpg

That is "good enough". For rev. b, I will put 1 mm more spacing between the IDC header and the components - that was a bit tight.

Revision d

(b and c was never produced)

This time with a proper STM32F103C8 (which isn't even proper technically).

Revision f

(revision e was rejected and never produced)

STM32 Programmer rev. f Schematics.svg

Between rev. d and rev. e, JLCPCB changed their capabilities requiring 4 mm between cutouts and pcb edge, causing rev. e to be rejected. Rev. f changed to 4 mm and was produced with the proper STM32F103CB officially having the full 128 kB of flash.

Firmware

There are a number of different options when it comes to firmware for the STM32 Programmer. While not identical, the design follows the design of the original ST-Link close enough that the original ST-Link firmware can run on it. This is however clearly troublesome from a legal and license perspective, so fortunately there are other ways.

Flashing the firmware, one will experience a bit of a chicken-egg problem. You actually need a st-link device to flash the first example.

The dodgy approach (original ST-Link firmware)

The original ST-Link firmware consists of a bootloader (presumably to add DFU capabilities to the STM32F103 which hasn't got it built-in) and an application.

Flash Unprotected Bootloader

Using a st-link device, flash the unprotected bootloader to the device:

lth@ncpws04:~/src/st-link/bootloaders$ st-flash write Unprotected-2-1-Bootloader.bin 0x8000000
st-flash 1.7.0-dirty
2022-10-28T12:50:15 INFO common.c: F1xx Medium-density: 20 KiB SRAM, 128 KiB flash in at least 1 KiB pages.
file Unprotected-2-1-Bootloader.bin md5 checksum: 13b196c92248569d3a4a867562229cd7, stlink checksum: 0x00211ccc
2022-10-28T12:50:15 INFO common.c: Attempting to write 16384 (0x4000) bytes to stm32 address: 134217728 (0x8000000)
2022-10-28T12:50:15 INFO common.c: Flash page at addr: 0x08000000 erased
2022-10-28T12:50:15 INFO common.c: Flash page at addr: 0x08000400 erased
2022-10-28T12:50:15 INFO common.c: Flash page at addr: 0x08000800 erased
2022-10-28T12:50:15 INFO common.c: Flash page at addr: 0x08000c00 erased
2022-10-28T12:50:15 INFO common.c: Flash page at addr: 0x08001000 erased
2022-10-28T12:50:15 INFO common.c: Flash page at addr: 0x08001400 erased
2022-10-28T12:50:15 INFO common.c: Flash page at addr: 0x08001800 erased
2022-10-28T12:50:16 INFO common.c: Flash page at addr: 0x08001c00 erased
2022-10-28T12:50:16 INFO common.c: Flash page at addr: 0x08002000 erased
2022-10-28T12:50:16 INFO common.c: Flash page at addr: 0x08002400 erased
2022-10-28T12:50:16 INFO common.c: Flash page at addr: 0x08002800 erased
2022-10-28T12:50:16 INFO common.c: Flash page at addr: 0x08002c00 erased
2022-10-28T12:50:16 INFO common.c: Flash page at addr: 0x08003000 erased
2022-10-28T12:50:16 INFO common.c: Flash page at addr: 0x08003400 erased
2022-10-28T12:50:16 INFO common.c: Flash page at addr: 0x08003800 erased
2022-10-28T12:50:16 INFO common.c: Flash page at addr: 0x08003c00 erased
2022-10-28T12:50:16 INFO common.c: Finished erasing 16 pages of 1024 (0x400) bytes
2022-10-28T12:50:16 INFO common.c: Starting Flash write for VL/F0/F3/F1_XL
2022-10-28T12:50:16 INFO flash_loader.c: Successfully loaded flash loader in sram
2022-10-28T12:50:16 INFO flash_loader.c: Clear DFSR
2022-10-28T12:50:16 INFO flash_loader.c: Clear CFSR
2022-10-28T12:50:16 INFO flash_loader.c: Clear HFSR
 16/ 16 pages written
2022-10-28T12:50:17 INFO common.c: Starting verification of write complete
2022-10-28T12:50:17 INFO common.c: Flash written and verified! jolly good!

Plugging the new st-link device into USB, the following will show in dmesg output:

[15019.853921] usb 1-4.2: new full-speed USB device number 15 using xhci_hcd
[15019.955446] usb 1-4.2: New USB device found, idVendor=0483, idProduct=3748, bcdDevice= 1.00
[15019.955452] usb 1-4.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[15019.955453] usb 1-4.2: Product: STM32 STLink
[15019.955454] usb 1-4.2: Manufacturer: STMicroelectronics
[15019.955455] usb 1-4.2: SerialNumber: 066FFF313841423043123519

Flash Firmware

After the bootloader has been loaded, the device can be flashed with the full firmware using the STLinkUpgrade:

ST-Link Upgrade initial flash.png

ST-Link after upgrade.png

The device will now identify like this:

[ 4348.823460] usb 2-4.2: New USB device found, idVendor=0483, idProduct=374b, bcdDevice= 1.00
[ 4348.823465] usb 2-4.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 4348.823467] usb 2-4.2: Product: STM32 STLink
[ 4348.823468] usb 2-4.2: Manufacturer: STMicroelectronics
[ 4348.823469] usb 2-4.2: SerialNumber: 066FFF313841423043123519
[ 4349.248184] usb-storage 2-4.2:1.1: USB Mass Storage device detected
[ 4349.248359] scsi host6: usb-storage 2-4.2:1.1
[ 4349.248817] cdc_acm 2-4.2:1.2: ttyACM0: USB ACM device
[ 4350.258276] scsi 6:0:0:0: Direct-Access     MBED     microcontroller  1.0  PQ: 0 ANSI: 2
[ 4350.258501] sd 6:0:0:0: Attached scsi generic sg3 type 0
[ 4350.258805] sd 6:0:0:0: [sdd] 72 512-byte logical blocks: (36.9 kB/36.0 KiB)
[ 4350.258959] sd 6:0:0:0: [sdd] Write Protect is off
[ 4350.258961] sd 6:0:0:0: [sdd] Mode Sense: 03 00 00 00
[ 4350.259127] sd 6:0:0:0: [sdd] No Caching mode page found
[ 4350.259129] sd 6:0:0:0: [sdd] Assuming drive cache: write through
[ 4350.275457] sd 6:0:0:0: [sdd] Attached SCSI removable disk

Black Magic

To be added.

Issues

In revision a I used Gigadevice GD32F103CB and on that version the ST-Link upgrade utility that come with STM32CubeIde refused to upgrade the devices. Revision d was made with STM32F103C8 (the 64 kB flash version) and that version did not have enough flash to install the firmware with MSC (Mass Storage Class) support. The strangely named "STM32+Audio" version installed fine and will upgrade.

Miscellaneous Links