Reading 1.8V flash with Raspberry Pi

Use Logic Level Shifter to read the flash operating under 3.3V.

Posted by Gyul on April 13, 2024

Introduction

I bought a router and it was using flash which is operating in 1.8V. Well, I don't have any programmer which supports 1.8V. So I bought it. The Level shifter. A programmer is too expensive. Level shifter was working perfectly and I was able to read the flash. Check this out.

Background


Flash

The flash was ESMT F50D1G4L8. It is SPI NAND Flash and working at 1.8V. Unfortunately the package is WSON-8. So there's no way to connect to the chip legs but to solder it. We will see this later.

Logic Level shifter

I bought a 8 Channel Level shifter(TXS0108E) which is made at Sparkfun. It has Supply Voltage Range as below. And it should be always VB >= VA when use.

  • VA : 1.4V to 3.6V
  • VB : 1.65V to 5.5V

So if we send signal with 3.3V in B1, the signal will be sent with 1.8 in A1. This is what Level shifter does.

A Raspberry pi use 3.3V on GPIO. So I will connect 3.3V at VB and connect 1.8V at VA. And also we should connect VA with OE to use this level shifter.

Extraction


Connecting wires

I soldered Enamel coated wires with Flash and also with Pin header which is connected with level shifter.

I finished solder all the pins without #WP and #HOLD pin.

But Raspberry pi doesn't have 1.8V power source. So I had to connect 1.8V power source on the device that the flash was attached.

Also when giving voltage with two different sources, we have to connect the ground of the two device. So I connected router and Raspberry pi's ground together.

And lastly I connected Raspberry pi's SPI interface pins with Level shifter.

Read Flash Memory

After all the connections, I read the flash memory using spidev module in python. I couldn't use flashrom as it doesn't support this chip(F50D1G4L8).

This chip reads data per page using 13h opcode. Then the datas are saved in the cache. The instruction sends as below.

  • Command (13h) + 8bits dummy + 16bits addresss

So we have to read the cache using 03h opcode to actually read the datas. The instruction sends as below.

  • Command (03h) + 4bits dummy + 12bits address + 8bits dummy

But we can leave the address zero after command(03h). Because we don't need to set the address of the cache. But what we have to change everytime is the page address above(13h).

I implemented the operation I told above with python code.

import spidev

spi = spidev.SpiDev()

spi.open(0,0)
spi.mode = 0
spi.max_speed_hz = 20000000
ROWSIZE = 0x10000

def flash_read(f):
    for i in range(0, ROWSIZE):
        spi.xfer2([0x13] + [0x00, i >> 8, i & 0xff]) # PAGE READ 

        data = spi.xfer2([0x03] + [0x00] * 2115) # Read From Cache
        data = data[4:] # Truncating first 4 bytes
        f.write(bytes(data))
        print(hex(i))

f = open("output.bin", "xb")

flash_read(f)

f.close()

The page size is 2KB + 64. And it has 0x10000 pages. So this will read all the pages.

And the datas are extracted successfully.

Copyright © FirmExtract 2024