back to index

FLASH and EEPROM memory tools
ch341A SPI/I2C programmer
      SPI families
flash equivalents

FLASH and EEPROM memory tools



ch341A SPI/I2C programmer

git clone https://github.com/plumbum/ch341eeprom
cd ch341eeprom
edit Makefile, replace "clang" with "gcc", appears to work
make
...and we have a tool that seems to work.

git clone https://review.coreboot.org/flashrom.git cd flashrom apt-get install libpci-dev make ./flashrom --programmer ch341a_spi ...seems to work
test chip not autodetected: Probing for Sanyo unknown Sanyo SPI chip, 0 kB: probe_spi_rdid_generic: id1 0x5e, id2 0x4014 Probing for Winbond unknown Winbond (ex Nexcom) SPI chip, 0 kB: probe_spi_rdid_generic: id1 0x5e, id2 0x4014 Probing for Generic unknown SPI chip (RDID), 0 kB: probe_spi_rdid_generic: id1 0x5e, id2 0x4014 Found Generic flash chip "unknown SPI chip (RDID)" (0 kB, SPI) on ch341a_spi. Probing for Generic unknown SPI chip (REMS), 0 kB: probe_spi_rems: id1 0x5e, id2 0x13 Found Generic flash chip "unknown SPI chip (RDID)" (0 kB, SPI).
This flash part has status NOT WORKING for operations: PROBE READ ERASE WRITE git clone https://github.com/danielkucera/ch341prog cd ch341prog make ...seems to work
windows software https://www.neven.cz/kategorie/elektronicke-soucastky/elektronicky-vyvoj/programatori-a-prislusenstvi-k-programovani/eeprom-flash-bios-usb-programator-s-cipem-ch341a-spi/ https://uloz.to/!uAtRPqSpk/ch341a-programming-software-rar ...seems to work
test chip not autodetected, manual forcing of Winbond W25X40L gives successful read (try with W25X80L, it's in fact 1-meg, not half-meg as the older ESP01 variants) Device reported its revision [4.03] Manufacturer ID: 5e Memory Type: 40 Capacity: 14 Chip capacity is 1048576 the chip is XTX pn25f08b 1-megabyte used in cheapo esp-01 modules also used in Sonoff devices (also esp8266) upgradable with WINBOND W25Q32FVSIG, from 1MB to 4MB datasheet: http://www.xtxtech.com/upfile/2016082517095182.pdf Table 8. PN25F08 ID Definition table Operation Code M7-M0 ID15-ID8 ID7-ID0 9FH E0 40 14 90H E0 13 ABH 13 (BEWARE: PN25F08B has mfg id 0x5E instead of 0xE0) apparently the newer Sonoffs use a different flash chip (PN25F08B) and it is then recommended to use these settings: Generic ESP8266 module Flash Mode: DOUT Flash Frequency: 40MHz CPU Frequency: 80MHz Flash Size: 1M (512K SPIFFS) Debug Port: Disabled Debug Level: None Reset Method: ck Upload Speed: 115200 Had to flash it a few times before it worked http://www.ti.com/lit/an/swra515/swra515.pdf example of generic SPI flash requirements: 1.2 Supported Flash Types For compatibility with the CC3x20 device, the serial flash device must support the following commands and format: • Uniform sector erase size of 4K • Command 0x9F (read the device ID [JEDEC]). Procedure: SEND 0x9F, READ 3 bytes • Command 0x05 (read the status of the SFLASH). Procedure: SEND 0x05, READ 1 byte. Bit 0 is busy and bit 1 is write enable • Command 0x06 (set write enable). Procedure: SEND 0x06, read status until write-enable bit is set • Command 0xC7 (chip erase). Procedure: SEND 0xC7, read status until busy bit is cleared • Command 0x03 (read data). Procedure: SEND 0x03, SEND 24-bit address, read n bytes • Command 0x02 (write page). Procedure: SEND 0x02, SEND 24-bit address, write n bytes (n=1..256) • Command 0x20 (sector erase). Procedure: SEND 0x20, SEND 24-bit address, read status until busy bit is cleared static int spi_chip_erase_60(struct flashctx *flash) /* This usually takes 1-85s, so wait in 1s steps. */ return spi_simple_write_cmd(flash, 0x60, 1000 * 1000); } static int spi_chip_erase_62(struct flashctx *flash) /* This usually takes 2-5s, so wait in 100ms steps. */ return spi_simple_write_cmd(flash, 0x62, 100 * 1000); } static int spi_chip_erase_c7(struct flashctx *flash) /* This usually takes 1-85s, so wait in 1s steps. */ return spi_simple_write_cmd(flash, 0xc7, 1000 * 1000); } int spi_block_erase_52(struct flashctx *flash, unsigned int addr, unsigned int blocklen) /* This usually takes 100-4000ms, so wait in 100ms steps. */ return spi_write_cmd(flash, 0x52, false, addr, NULL, 0, 100 * 1000); } * 32M (one die) for Micron */ int spi_block_erase_c4(struct flashctx *flash, unsigned int addr, unsigned int blocklen) /* This usually takes 240-480s, so wait in 500ms steps. */ return spi_write_cmd(flash, 0xc4, false, addr, NULL, 0, 500 * 1000); } * 64k for Macronix * 32k for SST * 4-32k non-uniform for EON */ int spi_block_erase_d8(struct flashctx *flash, unsigned int addr, unsigned int blocklen) /* This usually takes 100-4000ms, so wait in 100ms steps. */ return spi_write_cmd(flash, 0xd8, false, addr, NULL, 0, 100 * 1000); } * 4k for PMC */ int spi_block_erase_d7(struct flashctx *flash, unsigned int addr, unsigned int blocklen) /* This usually takes 100-4000ms, so wait in 100ms steps. */ return spi_write_cmd(flash, 0xd7, false, addr, NULL, 0, 100 * 1000); } int spi_block_erase_db(struct flashctx *flash, unsigned int addr, unsigned int blocklen) /* This takes up to 20ms usually (on worn out devices up to the 0.5s range), so wait in 1ms steps. */ return spi_write_cmd(flash, 0xdb, false, addr, NULL, 0, 1 * 1000); } int spi_block_erase_20(struct flashctx *flash, unsigned int addr, unsigned int blocklen) /* This usually takes 15-800ms, so wait in 10ms steps. */ return spi_write_cmd(flash, 0x20, false, addr, NULL, 0, 10 * 1000); } int spi_block_erase_50(struct flashctx *flash, unsigned int addr, unsigned int blocklen) /* This usually takes 10ms, so wait in 1ms steps. */ return spi_write_cmd(flash, 0x50, false, addr, NULL, 0, 1 * 1000); } int spi_block_erase_81(struct flashctx *flash, unsigned int addr, unsigned int blocklen) /* This usually takes 8ms, so wait in 1ms steps. */ return spi_write_cmd(flash, 0x81, false, addr, NULL, 0, 1 * 1000); } int spi_block_erase_60(struct flashctx *flash, unsigned int addr, unsigned int blocklen) if ((addr != 0) || (blocklen != flash->chip->total_size * 1024)) { msg_cerr("%s called with incorrect arguments\n", __func__); return -1; } return spi_chip_erase_60(flash); } int spi_block_erase_62(struct flashctx *flash, unsigned int addr, unsigned int blocklen) if ((addr != 0) || (blocklen != flash->chip->total_size * 1024)) { msg_cerr("%s called with incorrect arguments\n", __func__); return -1; } return spi_chip_erase_62(flash); } int spi_block_erase_c7(struct flashctx *flash, unsigned int addr, unsigned int blocklen) if ((addr != 0) || (blocklen != flash->chip->total_size * 1024)) { msg_cerr("%s called with incorrect arguments\n", __func__); return -1; } return spi_chip_erase_c7(flash); } int spi_block_erase_21(struct flashctx *flash, unsigned int addr, unsigned int blocklen) /* This usually takes 15-800ms, so wait in 10ms steps. */ return spi_write_cmd(flash, 0x21, true, addr, NULL, 0, 10 * 1000); } int spi_block_erase_5c(struct flashctx *flash, unsigned int addr, unsigned int blocklen) /* This usually takes 100-4000ms, so wait in 100ms steps. */ return spi_write_cmd(flash, 0x5c, true, addr, NULL, 0, 100 * 1000); } int spi_block_erase_dc(struct flashctx *flash, unsigned int addr, unsigned int blocklen) /* This usually takes 100-4000ms, so wait in 100ms steps. */ return spi_write_cmd(flash, 0xdc, true, addr, NULL, 0, 100 * 1000); } QIO - SPI host uses the "Quad I/O Fast Read" command (EBh). Four SPI pins are used to write the flash address part of the command, and to read flash data out. Therefore these phases need a quarter the clock cycles compared to standard SPI. QOUT - SPI host uses the "Quad Output Fast Read" command (6Bh). Four SPI pins are used to read the flash data out. Slightly slower than QIO, because the address is written via the single MOSI data pin. DIO - SPI host uses the "Dual I/O Fast Read" command (BBh). Two SPI pins are used to write the flash address part of the command, and to read flash data out. Therefore these phases need half the clock cycles compared to standard SPI. DOUT - SPI host uses the "Dual Output Fast Read" command (3Bh). Two SPI pins are used to read flash data out. Slightly slower than DIO, because the address is written via the single MOSI data pin. In terms of performance: QIO > QOUT > DIO > DOUT (source) [ref] SPI - Single-channel dual-SPI quad-SPI QPI - Quad-channel DTR - Dual Transfer Rate RPMC - Replay-Protection Monotonic Counter SFDP - Serial Flash Discoverable Parameters (command 0x5A) https://chromium.googlesource.com/chromiumos/platform/ec/+/master/include/sfdp.h 4-byte addressing: for over 128Mbit/16Mbyte, up to 32Gbit/Gbyte

SPI families

Winbond W25X - SPI, dualSPI; 4k/32k/64k erase
Winbond W25Q - superset of W25X; SPI, dualSPI, quadSPI, QPI; SFDP; 4k/32k/64k erase



flash equivalents

https://www.macronix.com/zh-tw/products/Documents/Macronix%20NOR%20and%20NAND%20Flash%20Cross%20Reference%20Guide.pdf

MX30LF1G18AC - Macronix
S34ML01G1 - Cypress
S34ML01G2 - Cypress
H27U1G8F2B - Hynix
H27U1G8F2C - Hynix
MT29F1G08ABADA - Micron
MT29F1G08ABAEA - Micron
K9F1G08U0D - Samsung
K9F1G08U0E - Samsung
W29N01GV - Winbond
W29N01HV - Winbond




If you have any comments or questions about the topic, please let me know here:
Your name:
Your email:
Spambait
Leave this empty!
Only spambots enter stuff here.
Feedback: