Skip to content
Workshop: repairs and experiments

Bosch dishwasher board SWS4118: copying the STM32 firmware with an ST-Link (part 2)

Published 12.11.2026
Contents 5
  1. The STM32 microcontroller, read only
  2. What we read
  3. Next
  4. Safety
  5. Article changelog

The second part about the Bosch dishwasher board 702168823.01GA / SWS4118 Rev.4. Part one covers what is on the board and the EEPROM copy. This part is about the STM32 microcontroller, read only:

  • where the SWD pins are and what the X20 pads carry;
  • how to connect an ST-Link V2 (and, in a collapsed block, a Raspberry Pi);
  • which software and drivers you need and where to get them;
  • how to check whether the firmware is read-protected;
  • how to make a copy and how to make sure it is correct;
  • what we read from our board.

What the firmware itself can do and what use it is to us is in part three.

draft, still being discussed and extended

⚠ The board runs straight off 230 V mains with no isolation. While a programmer is connected, the board stays off the mains: it gets only 3.3 V, from the ST-Link or a separate supply. Otherwise mains voltage ends up on the computer's USB.

The STM32 microcontroller, read only

The aim of this step is to find out exactly which chip this is, whether the firmware is protected against reading, and if not, to save a copy. Nothing is written or erased. The CH341B programmer will not help here: an STM32 is read over SWD, which the CH341 does not have. We read it with an ST-Link V2 (a cheap clone); how to do the same with a Raspberry Pi 3B+ is in the collapsible block below.

Where to find the pins

STM32 microcontroller, 24C08 EEPROM and X20 pads with letter markers
The microcontroller area: A the STM32, B the 24C08WP EEPROM, D the X20 pads, E another group of test pads. More on each component in part one.
STM32 in an LQFP100 package: where to find the SWD, reset and power pins — oriented as in the photoSTM32F301VCT61–25 →26–50 →← 51–75← 76–100pin-1 dot75 VDD·3.3 V74 VSS·GND72 SWDIO (PA13)69 RX (PA10)68 TX (PA9)76 SWCLK (PA14)94 BOOT099 VSS·GND100 VDD·3.3 V14 NRST — resetpins numbered anticlockwise from pin 1
The LQFP100 package in the same orientation as the microcontroller photo above: the marking reads the right way up, with the pin-1 dot at the bottom left. Pin 1 is the leftmost pin on the bottom side, and the numbering runs anticlockwise from there.
PinSignalWhat forNeeded for reading
72PA13, SWDIOdebugger datayes
76PA14, SWCLKdebugger clockyes
14NRSTresetadvisable: helps if the link will not come up
99, 74VSSGNDyes (any GND point on the board)
100, 75VDD3.3 Vboard power
94BOOT0boot mode selectno, leave it alone
68, 69PA9, PA10USART1: ST's built-in bootloaderno (a fallback route: needs BOOT0 = 1, and read protection applies here too)
  • The pin numbers are ST's standard 100-pin layout (as on the STM32F303VC). They have not yet been checked against a datasheet for a chip marked STM32F301 VCT6, so first check the orientation with a multimeter: pins 99 and 74 should ring through to GND (for example, to EEPROM pin 4), and 100 and 75 to the 3.3 V rail (EEPROM pin 8). If they match, the numbers are right.
  • Do not solder to the pins: at 0.5 mm pitch it is easy to bridge neighbours.

What the X20 pads carry (D in the microcontroller photo; counted left to right as in the photo, along the bottom of the board), traced with a continuity tester:

X20 padGoes toWhat it is
1pin 76SWCLK (PA14)
2pin 72SWDIO (PA13)
3pin 14NRST (reset), not direct but through a 220 Ω resistor (marked 221)
4pin 90PB4 (NJTRST in JTAG); the firmware keeps it as an input, and on the live board it reads logic 1
5GNDcommon ground
63.3 Vthe 3.3 V supply rail

So X20 is a debug connector: SWD and reset are already on it, and the X20 pads are a convenient place for probes or soldered wires.

X20 pads and the traces from pads 3 and 4: pad 3 through resistor 221 to NRST, pad 4 to pin 90
Tracing pads 3 and 4. Red line: pad 3 → resistor 221 (220 Ω) → pin 14, NRST, on the bottom side of the package. Green: pad 4 → pin 90 on the left side of the package.
  • The 220 Ω resistor in the reset line does no harm: the ST-Link pulls NRST to ground, and 220 Ω only limits the current, most likely in case the pad is shorted to the supply by accident.
  • Pad 4 (PB4) is not needed for reading. The firmware sets it up as an input without an internal pull resistor, and on the live board it reads 1, so there is probably an external pull-up. It may be a factory service-mode input; what it does has not yet been found in the firmware. Do not short it to ground on a working board until we know what it is.

Checked against an open description. The hn/bsh-home-appliances project describes Bosch dishwasher power modules with the same STM32F301VCT6 and gives this X20 order: SWCLK, SWDIO, BOOT0, RESET, GND, 3.3 V. The first two and the last two pads match what we traced. Pads 3 and 4 are different on our board: 3 is NRST (pin 14), 4 is PB4 (pin 90), and BOOT0 is not brought out to X20. So either hn's boards are a different revision or that description has the order mixed up: trust the continuity check on your own board.

Connecting an ST-Link V2

Connecting an ST-Link V2 to the board's X20 test pads: SWCLK, SWDIO, GND and 3.3 VST-Link V2header on the caseSWCLKSWDIORSTGND3.3 VX20 pads on the boardleft to right, as in the photo1 · SWCLK (76, PA14)2 · SWDIO (72, PA13)3 · NRST (14, via 220 Ω)4 · pin 90 (PB4)5 · GND6 · 3.3 VRST to pad 3 is optional: only if the link will not come up without a resetboard off the mains; 3.3 V from the ST-Link or a separate supply, never both
The ST-Link V2 and the X20 pads: SWCLK (yellow) to pad 1, SWDIO (green) to pad 2, GND to pad 5, 3.3 V to pad 6. RST (dashed) goes to pad 3 and is optional: you need it if the link will not come up without a reset.
ST-Link V2X20 padOn the board
SWCLK1pin 76 (PA14)
SWDIO2pin 72 (PA13)
GND5GND
3.3 V63.3 V rail
RST3NRST, pin 14 (through 220 Ω), if needed
  • Power. On cheap ST-Link clones the 3.3 V pin is an output: it powers the board, so no separate supply is needed, and none should be connected: two sources on one rail fight each other. On a genuine ST-Link this pin only senses the voltage: then a separate 3.3 V supply powers the board, and pad 6 is wired to the ST-Link's 3.3 V pin for sensing. Once connected, measure the voltage on pad 6: it should be ≈ 3.3 V. If a clone gives less than about 3 V, its regulator cannot carry the board: disconnect its 3.3 V pin and power the board from a separate supply (shared GND).
  • Keep the board off the mains the whole time. It is not galvanically isolated from the mains: plugging it into a socket with the ST-Link connected puts mains voltage on the computer's USB.
  • Keep the wires short (15–20 cm at most).
  • Software: ST's STM32CubeProgrammer (Windows, Linux, macOS) or OpenOCD. On Windows, the ST-Link driver is installed together with STM32CubeProgrammer.
How to connect a Raspberry Pi 3B+ instead of an ST-Link
Connecting a Raspberry Pi 3B+ to the STM32 SWD on the board: SWCLK, SWDIO, GND and NRSTRaspberry Pi 3B+GPIO header (pins)Dishwasher boardon the X20 pads: 1 SWCLK, 2 SWDIO, 3 NRST, 5 GND, 6 3.3 Vpin 22 · GPIO25SWCLK — PA14 (76)pin 18 · GPIO24SWDIO — PA13 (72)pin 20 · GNDGNDpin 12 · GPIO18NRST (14) — optional3.3 V to the board from a separate supply (GND shared with the Pi)board off the mains; read only
A Raspberry Pi 3B+ and the board's SWD pins: SWCLK, SWDIO, GND, and the optional NRST dashed. The numbers are the physical pins of the Pi's 40-pin header.
Raspberry Pi 3B+ pinPi signalOn the board
22GPIO25SWCLK, X20 pad 1, pin 76
18GPIO24SWDIO, X20 pad 2, pin 72
20GNDGND, X20 pad 5
12GPIO18NRST, X20 pad 3, pin 14

Power the board with 3.3 V from a separate supply (X20 pad 6), with GND shared with the Pi: better not to load the Pi's own 3.3 V pin with the board. The software is OpenOCD:

sudo apt install openocd telnet
sudo openocd -f interface/raspberrypi2-native.cfg -c "transport select swd" -f target/stm32f3x.cfg -c "adapter speed 100"

If OpenOCD reports that raspberrypi2-native.cfg does not exist, your version has merged it into interface/raspberrypi-native.cfg. After that, use the same commands in telnet localhost 4444 as for the ST-Link below.

Software and drivers

WhatWhere to get itWhat for
STM32CubeProgrammerst.com: STM32CubeProg, free; downloading needs an ST accountreading the flash and option bytes; it has both a window and a command-line STM32_Programmer_CLI
ST-Link driver for Windowsinstalled together with STM32CubeProgrammer; separately as STSW-LINK009so that Windows can see the ST-Link
OpenOCDLinux: sudo apt install openocd; Windows: xPack OpenOCD buildsa free alternative; works with both an ST-Link and a Raspberry Pi
Ghidraghidra-sre.organalysing the firmware copy on a computer

On Windows the command-line program ends up here after installation:

C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin\STM32_Programmer_CLI.exe

Below we simply write STM32_Programmer_CLI: either add the bin folder to PATH or run the commands from it.

The steps in short:

  1. The board stays off the mains. Wire the ST-Link to X20 as in the diagram above, then plug it into USB.
  2. Check that the computer sees the ST-Link: STM32_Programmer_CLI -l st. It lists the ST-Link, its firmware version and its serial number (if you publish the output, better remove the number).
  3. Check the protection: STM32_Programmer_CLI -c port=SWD mode=HOTPLUG freq=100 -ob displ. An RDP line reading 0xAA (Level 0, no protection) means there is no protection and the firmware can be read. The other values are explained in the next section.
  4. Read the firmware twice and compare the copies: see If there is no protection: a copy.

Can the firmware be saved?

An STM32 has read protection, the RDP level (0, 1 or 2), and whether the firmware can be read depends on it.

STM32CubeProgrammer (the easiest way). Choose ST-LINK, connection mode "Normal" (or "Hot plug", to connect without resetting the microcontroller), and press Connect. The software shows the chip name and flash size, and the OB (Option bytes) tab shows RDP: AA is level 0, CC is level 2, BB or anything else is level 1. Do not change anything on the OB tab and do not press Apply. If the software offers to update the ST-Link's own firmware, decline: clones sometimes stop working after such an update.

OpenOCD (Windows, Linux):

openocd -f interface/stlink.cfg -f target/stm32f3x.cfg -c "adapter speed 100"

Once OpenOCD has found the microcontroller, in a second window:

telnet localhost 4444

and there, one at a time (each command only reads):

mdw 0xE0042000
mdh 0x1FFFF7CC
mdw 0x4002201C
mdb 0x1FFFF800 16
CommandWhat it showsHow to read it
mdw 0xE0042000the device IDthe last three hex digits: 422 is the F302/F303 family with 128–256 KB; 439 is F301/F302 with 32–64 KB; 446 is F302/F303 with 384–512 KB
mdh 0x1FFFF7CCflash size in KB0x0100 = 256 KB, 0x0040 = 64 KB
mdw 0x4002201Cthe FLASH_OBR registerbits 2–1: 00 is level 0, 01 is level 1 (a last hex digit of 0 or 1 means level 0; 2 or 3 means level 1)
mdb 0x1FFFF800 16option bytes, the chip settingsa first byte of aa means level 0
ResultLevelWhat it meansWhat we do
bits 2–1 = 00, first option byte aa0no protectionsave the whole flash (below)
bits 2–1 = 01, first byte something else (not aa)1the flash cannot be read over SWDthe firmware cannot be copied. Protection can only be removed together with erasing all the firmware, and we do not do that
the software cannot see the microcontroller although the wiring has been checkedpossibly 2debugging is disabled for goodthe firmware can be neither read nor replaced; first check the wires, power and NRST again

If there is no protection: a copy

In STM32CubeProgrammer: the "Memory & File editing" tab (the pencil icon), address 0x08000000, size 0x40000 (256 KB; if the software showed a different flash size after Connect, use that), Read, then Save As… to a file. Do it twice and compare the files.

From the STM32CubeProgrammer command line (this is how we read it; every command only reads):

STM32_Programmer_CLI -c port=SWD mode=HOTPLUG freq=100 -ob displ
STM32_Programmer_CLI -c port=SWD mode=HOTPLUG freq=100 -u 0x08000000 0x40000 flash_1.bin
STM32_Programmer_CLI -c port=SWD mode=HOTPLUG freq=100 -u 0x08000000 0x40000 flash_2.bin
STM32_Programmer_CLI -c port=SWD mode=HOTPLUG freq=100 -u 0x1FFFF800 0x10 optbytes.bin
  • mode=HOTPLUG connects without resetting the microcontroller: its program keeps running.
  • freq=100 means 100 kHz: slow (one 256 KB copy takes ≈ 33 s), but reliable even with probe wires.
  • -u (upload) means reading from the microcontroller into a file, confusing as the name is. Writing to the microcontroller is done by -d and -w, erasing by -e; we do not use those here.
  • To compare the copies: on Windows fc /b flash_1.bin flash_2.bin ("FC: no differences encountered" means identical), on Linux cmp flash_1.bin flash_2.bin (no output means identical). Or compare checksums: certutil -hashfile flash_1.bin SHA256 on Windows, sha256sum flash_*.bin on Linux.

In OpenOCD, in the same telnet window:

halt
dump_image flash_1.bin 0x08000000 0x40000
dump_image flash_2.bin 0x08000000 0x40000
dump_image optbytes.bin 0x1FFFF800 16
resume
  • 0x40000 is 256 KB. If mdh 0x1FFFF7CC showed a different size, use that instead: the size in KB × 1024, in hex.
  • halt only stops the program running and resume continues it; nothing is written.
  • The files appear in the folder OpenOCD was started from. The two copies must be identical (cmp flash_1.bin flash_2.bin) and must not be all FF or all 00.

What else to save

WhatWhereWhyIn the article
the firmware (flash)0x08000000, 256 KBthe master copy, so we can always go backno: it is the manufacturer's program
option bytes0x1FFFF800, 16 bytesthe protection level and chip settingsyes, the values and what they mean
device ID, flash size0xE0042000, 0x1FFFF7CCthe exact modelyes
the chip's unique ID0x1FFFF7AC, 12 bytesidentifies this particular chipno, it is private
the 24C08WP EEPROMpart onesettings and countersby the part one rule
ST's built-in bootloadersystem memorythe same on every such chip, no need to save it—

What you can do without breaking anything

Allowed (read only)Why
read the device ID, flash size and option bytesto know what the chip is and how it is configured
read the flash and RAMa copy of the firmware; the state of variables while running
read peripheral registers (GPIO, timers, UART settings; not the UART and SPI data registers, as reading them clears their flags)to learn which pins drive the inverter PWM and which UART goes to the panel
halt / resumestop the program to look at its state, then carry on
analyse the firmware copy on a computer (Ghidra: ARM Cortex-M, base 0x08000000)to find how the board receives the "run the pump" command and the PWM settings
Not allowed: it breaks something, or breaks it for goodWhat happens
removing level 1 protection (stm32f1x unlock, setting RDP to 0)all the firmware is erased
setting level 2debugging is disabled for good; there is no way back
flash erase…, flash write…, program, "Erase", "Program", "Download"the firmware is erased or replaced
changing the option bytes (stm32f1x options_write)can turn on protection or change how the chip behaves
connecting the board to the mains while a Pi or programmer is connectedmains voltage on the Pi and the computer

The rule for this step: every command here only reads. If any software offers to erase, write or "unlock" anything, the answer is no.

What we read

We read it with an ST-Link V2 clone connected to the X20 pads: pad 1 SWCLK, pad 2 SWDIO, pad 5 GND, pad 6 3.3 V. The ST-Link itself powered the board. Pads 3 (NRST) and 4 were left unconnected: no reset was needed. The commands are the ones in the copy section, run from the STM32CubeProgrammer v2.23 command line.

WhatResult
board voltage (from the ST-Link)3.26 V
device ID0x422, revision Y: the STM32F302xB/xC and F303xB/xC family, Cortex-M4 core
flash256 KB (0x1FFFF7CC = 0x0100)
read protection (RDP)0xAA: level 0, no protection
write protectionoff on all areas
option bytesaa 55 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00 ff 00: factory values
firmware copysaved: two 256 KB copies, byte-for-byte identical; ≈ 33 s each
option bytes copysaved, 16 bytes

The marking does not match the die. The package says STM32F301 VCT6, but the die identifies as an STM32F302/F303 with 256 KB (the F301 line has ID 0x439 and at most 64 KB). The chip looks like it was marked to order for the board maker. For working with it we use the STM32F302VC / F303VC documentation. Judging by the blocks the firmware uses (the TIM8 timer, six comparators, four op-amps), it is most likely an STM32F303xC; see part three. The pinout agrees: SWD really is on pins 72 and 76, as on the F303VC.

What we saved besides the firmware: the option bytes (16 bytes), the device ID and flash size, and the die's unique number (0x1FFFF7AC, 12 bytes). The unique number stays in private notes only: it identifies this one die. It can be read like this:

STM32_Programmer_CLI -c port=SWD mode=HOTPLUG freq=100 -r32 0x1FFFF7AC 12

We do not publish the firmware itself: it is the manufacturer's program. What is inside it is in part three.

Next

  1. Now that we have a copy, we can safely take the firmware apart. That is part three: what it consists of, which parts of the chip are in use, how the board talks to the panel, and what use all this is to us.
  2. Pads 3 and 4 of X20 have been traced (NRST and PB4): see the table above.
  3. The EEPROM and the rest of the board are in part one.

Safety

  • Do not plug the board into the mains while an ST-Link or Raspberry Pi is connected. The board is not isolated from the mains: mains voltage would end up on the computer's USB.
  • The bus capacitor holds ~325 V for anything from a few seconds to a few minutes after switch-off. Before touching a board that has been on the mains, measure the voltage across it.
  • Read only. If any software offers to erase, write or "unlock" anything, the answer is no.

Article changelog

  • 2026-11-10 — first draft: split off from part one (step 2, the STM32); added software and drivers, the steps in short, command-line commands, the results from our board, and a check of X20 against an open description.
  • 2026-11-10 — X20 pads 3 and 4 traced: 3 is NRST through 220 Ω, 4 is pin 90 (PB4); a tracing photo; the ST-Link and Raspberry Pi diagrams updated.