This is an old revision of the document!
these are my notes on how I dump SPI flash.
Since flash uses kind of another technology, it is often hard or expensive to add flash memory in integrated circuits (IC), mainly micro-controller (MCU). Thus MCU have either very limited flash size (< 1 MB), or you have to provide it externally. Externally dedicated flash is very common and inexpensive. Some system on a chip (SoC) even just add the flash die next to the MCU die (this is called package in/on package).
The most common package for flash is SOIC-8 (surface mount, 8 pins, 1.27 mm pin pitch, 200 mil wide body). More compact alternatives are WSON/LGA (without external lead) and BGA (allowing more pins underneath). Whenever you find such a chip with 25 on the top marking, it is very probably a flash chip.
The most common interface is Serial Peripheral Interface (SPI). It allows extremely fast transfer rates (clock frequency > 100 MHz) and is supported by most MCU. For even faster communication, high-end chips even provide quad output support (QSPI).
The pinout is (almost) always the same to provide interoperability. The difference between models is mainly the size (obviously), and features (i.e. speed).
By far the easiest method is to de-solder the chip and place it in a dedicated programmer. The only disadvantage is that you will have to de-solder and re-solder the chip every time you want to read or write it.
The cheapest, and crudest, way to read/write SPI flash is using a CH341A based programmer. You can find them for less than $3.
Solder the SPI flash to a DIP-8 adapter board, and place it in the ZIF socket (Zero-Insertion-Force). Insert it as depicted on the side for the 25xx (furthest away from the lever, with pin 1 notch facing the lever). To avoid soldering the chip on an adapter board, use sockets with spring contacts (the contacts need to be clean for it to work well). Be sure the jumper shorts pin 1 and 2 on the side (shorting pins 2 and 3 switched the CH341A to UART mode).
As software we will use ch341prog. Verify if the chip is detected correctly, then read the memory out:
ch341prog --info Device reported its revision [4.03] Manufacturer ID: ef Memory Type: 4016 No CFI structure found, trying to get capacity from device ID. Set manually if detection fails. Capacity: 16 Chip capacity is 4194304 bytes ch341prog --read spi.bin ... Read started!
The TL866A (aka. MiniPRO) is the next step up, and still cheap (< $30).
To dump SPI flash, we will use minipro.
# search for the right part using the top marking on the chip minipro --search 25q32bv Found TL866A 03.2.86 (0x256) W25Q32BV W25Q32BV@WSON8 W25Q32BV@SOIC8 W25Q32BV@SOIC16 W25Q32BV(OTP) W25Q32BV(OTP)@WSON8 W25Q32BV(OTP)@SOIC8 W25Q32BV(OTP)@SOIC16 # read the device ID to be sure the connection work (it's not get_id as in the help, but read_id) minipro --device 'W25Q32BV@SOIC8' --read_id Found TL866A 03.2.86 (0x256) Chip ID OK: 0xEF4016 # alternatively, let it find which 25xx SPI 8-pin flash it is minipro --auto_detect 8 Found TL866A 03.2.86 (0x256) Autodetecting device (ID:0xEF4016) S25FL032K@SOIC8 W25Q32@MLP8 W25Q32(OTP)@MLP8 W25Q32BV W25Q32BV@WSON8 W25Q32BV@SOIC8 W25Q32BV(OTP) W25Q32BV(OTP)@WSON8 W25Q32BV(OTP)@SOIC8 W25Q32FV W25Q32FV@WSON8 W25Q32FV@SOIC8 W25Q32FV(OTP) W25Q32FV(OTP)@WSON8 W25Q32FV(OTP)@SOIC8 W25Q32V@MLP8 W25Q32V(OTP)@MLP8 17 device(s) found. # now read the memory minipro --device 'W25Q32BV@SOIC8' --read spi.bin Found TL866A 03.2.86 (0x256) Chip ID OK: 0xEF4016 Reading Code... 40.53Sec OK
The Batronix BX48 Batego is my high end programmer.
Yes, it is expensive (> $500), but the hardware is good, and what you pay for is the support. And I have to say that it is excellent. Is a chip missing? Just ask them and they will swiftly add support for it.
Note: This device is obsolete now, replaced by the BX48 Batego II. The main difference is that the Batego I does not support VPP > 15V (only required by very old NMOS EPROM). It still seems to be supported though.
The software is Prog-Express, and there is even support for Linux (a bit lagging the Windows release). There is an auto-detect function, but I am too concerned it accidentally damages the chip. Therefor I still select the target chip by hand.
On my setup it is not able to open the file dialog to allow me setting where I want to load/save the file (using version 3.8.8). To circumvent the issue I open the built-it hex-editor. There I can save read/write the data content, and save/load it.
To get the latest chip database (particularly if the Linux release it lagging), here how I update it:
wget https://www.batronix.com/downloads/ChipDBUpdate/ChipDB.zip unzip ChipDB.zip sudo mv /usr/lib/prog-express/ChipDB.db3 /usr/lib/prog-express/ChipDB.db3.bak sudo mv ChipDB.db3 /usr/lib/prog-express/ChipDB.db3 rm ChipDB.zip