Eight pin SPI flash chips are a cheap and easy way to add storage to your project. They’re available in sizes from 1MB to 128MB, and can be used to store data, firmware, or even a filesystem. They’re commonly found on PC motherboards for storing BIOS, FPGAs for storing bitstreams, and even the Bus Pirate for storing the firmware.

🛒

Get Bus Pirate & Accessories

Connections

Bus PirateSPI FlashDescription
CS/IO5CSChip select
MISO/IO4DOMISO Controller Data In
MOSI/IO7DIMOSI Controller Data Out
CLK/IO6CLKSPI Clock
WP/IO3WPWrite Protect, HIGH to disable
HOLD/IO2HOLDHold, HIGH to disable
VoutVCC3.3volt power supply
GNDGNDGround

Connect the Bus Pirate to the SPI flash chip as shown in the table above. Don’t forget the the write protect (WP) and hold pins, or the chip may not behave normally.

SPI Flash Adapters

PackageChipCapacity
DIP8Winbond W25Q80BV8Mbit
SOP8Winbond W25Q80DV8Mbit
WSON8Winbond W25Q64CV64Mbit

Flash adapter boards include a sample chip so you can get started right away. This demo uses the chips included with the adapters. The datasheets are linked above.

See it in action

Setup

Bus Pirate [/dev/ttyS0]
HiZ> m spi

Mode: SPI
SPI speed
 1 to 62500kHz
 x. Exit
kHz (100kHz*) > 100
Data bits
 4 to 8 bits
 x. Exit
Bits (8*) > 8
Clock polarity
 1. Idle LOW*
 2. Idle HIGH
 x. Exit
Polarity (1) > 1
Clock phase
 1. LEADING edge*
 2. TRAILING edge
 x. Exit
Phase (1) > 1
Chip select
 1. Active HIGH (CS)
 2. Active LOW (/CS)*
 x. Exit
CS (2) > 2
Actual speed: 99kHz
SPI> 

The most common NOR flash chips have an SPI interface. Flash chips are generally capable of 104MHz, but due to the adapter, cable length, breadboard, and other factors, we’ll use a low low speed of 100kHz.

  • m spi - change to SPI mode, or just hit m to select from the menu.
  • 100 - set SPI speed to 100kHz.
  • Hit enter to select the default values for the other options (8 data bits, idle low, leading edge, CS active low)

Power supply

According to the datasheet, the W25QxxxV series of chips can operate at 2.5 to 3.6 volts, with a slightly higher minimum voltage for speeds above 80MHz.

Image source: datasheet

Bus Pirate [/dev/ttyS0]
SPI> W 3.3
3.30V requested, closest value: 3.30V
300.0mA requested, closest value: 300.0mA

Power supply:Enabled
Vreg output: 3.3V, Vref/Vout pin: 3.2V, Current: 2.9mA

SPI> 

Let’s set the Bus Pirate to power the chip at 3.3volts, a very common voltage for modern SPI devices.

WP and HOLD pins

Most SPI flash chips have a write protect pin (WP) that prevents accidental writes, and a hold pin (HOLD) that pauses the chip.

  • HOLD must be held high or the chip won’t respond.
  • WP must be held high or the chip will be read only.
Bus Pirate [/dev/ttyS0]
SPI> A 2; A 3
IO2 set to OUTPUT: 1

IO3 set to OUTPUT: 1

SPI> 

Set HOLD (IO2) and WP (IO3) high with the auxiliary pin commands.

  • A 2; A 3 - Use Auxiliary pin control to set IO2 and IO3 high

Identify the chip

DeviceManufacturer IDDevice IDJEDEC ID
W25Q80BV0xEF0x130xEF 0x40 0x14
W25Q80DV0xEF0x130xEF 0x40 0x14
W25Q64CV0xEF0x160xEF 0x40 0x17

SPI flash chip commands are loosely standardized on some historical trends, but each manufacturer tends to add their own extensions.

Reset ID

The Reset ID is available immediately after the chip is reset. Write instruction 0xAB and three dummy bytes, then read the one byte reset ID.

  1. CS pin is pulled low
  2. Send the instruction 0xAB
  3. Send three dummy bytes 0x00
  4. Read the reset ID/device ID byte
  5. CS pin is pulled high
Bus Pirate [/dev/ttyS0]
SPI> [0xb9] D:10 [0xab 0x00:3 r]

CS Enabled
TX: 0xB9 
CS Disabled
Delay: 10ms
CS Enabled
TX: 0xAB 0x00 0x00 0x00 
RX: 0x13 
CS Disabled
SPI> 

Let’s reset the chip and read the reset ID.

  • [ - Start of SPI transaction. Lowers the CS pin to ground.
  • 0xb9 - Write the Power Down instruction.
  • ] - End of SPI transaction. Raises the CS pin to 3.3volts.
  • D:10 - Delay 10ms.
  • [ - Start of SPI transaction. Lowers the CS pin to ground.
  • 0xab - Write the Reset ID instruction.
  • 0x00:3 - Write three dummy bytes using the repeat command.
  • r - Read a one byte response.
  • ] - End of SPI transaction. Raises the CS pin to 3.3volts.

The response 0x13 (or 0x16 for W25Q64) is the reset ID of the flash chip.

Read Electronic Manufacturer ID

The Read Electronic Manufacturer ID instruction 0x90 returns a one byte manufacturer ID and a one byte device ID.

  1. CS pin is pulled low
  2. Write the Read Electronic Manufacturer ID instruction 0x90
  3. Write the 24 bit (3 byte) address 0x000000
  4. Read the Manufacturer ID and Device ID bytes
  5. CS pin is pulled high
Bus Pirate [/dev/ttyS0]
SPI> [0x90 0x00:3 r:2]

CS Enabled
TX: 0x90 0x00 0x00 0x00 
RX: 0xEF 0x13 
CS Disabled
SPI> 

The Read Electronic Manufacturer ID does not require a reset, we can issue this command at any time.

  • [ - Start of SPI transaction. Lowers the CS pin to ground.
  • 0x90 - Write the Read Electronic Manufacturer ID instruction.
  • 0x00:3 - Write the 24 bit (3 byte) address 0x000000.
  • r:2 - Read two bytes of data. The first byte is the manufacturer ID, the second byte is the device ID.
  • ] - End of SPI transaction. Raises the CS pin to 3.3volts.

0xEF is the manufacturer ID: Winbond. 0x13 (or 0x16 for W25Q64) is the device ID of the flash chip, same as the Reset ID command.

Read JEDEC ID

The Read JEDEC ID instruction 0x9F returns a three byte response. The first byte of the response is the Manufacturer ID. Winbond uses the second byte as a memory type ID and the third byte as a capacity ID, but this varies by manufacturer.

  1. CS pin is pulled low
  2. Write the Read JEDEC ID instruction 0x9F
  3. Read the manufacturer ID, Memory Type ID and Capacity ID bytes
  4. CS pin is pulled high
Bus Pirate [/dev/ttyS0]
SPI> [0x9F r:3]

CS Enabled
TX: 0x9F 
RX: 0xEF 0x40 0x14 
CS Disabled
SPI> 

Unlike the previous two ID instructions, the Read JEDEC ID command does not require (dummy) address bytes. The instruction is executed and the response is returned immediately.

  • [ - Start of SPI transaction. Lowers the CS pin to ground.
  • 0x9F - Write the Read JEDEC ID instruction.
  • r:3 - Read three bytes of data. The first byte is the manufacturer ID, the second byte is the memory type ID, and the third byte is the capacity ID.
  • ] - End of SPI transaction. Raises the CS pin to 3.3volts.

The manufacturer ID is 0xEF: Winbond. Memory type ID is 0x40, and the capacity ID is 0x14 (or 0x17 for W25Q64).

Read SFDP tables

The Read SFDP tables instruction 0x5A returns up to 256 bytes of data.

  1. CS pin is pulled low
  2. Write the Read SFDP instruction 0x5A
  3. Write the 3 byte address 0x00000000 that indicates where we want to being reading within the 256 byte SFDP table
  4. Write one dummy byte 0x00
  5. Read the SFDP table header (8 bytes)
  6. CS pin is pulled high
Bus Pirate [/dev/ttyS0]
SPI> [0x5A 0x00:3 0x00 r:8]

CS Enabled
TX: 0x5A 0x00 0x00 0x00 0x00 
RX: 0x53 0x46 0x44 0x50 0x05 0x01 0x00 0xFF 
    
CS Disabled
SPI> 

Send the ‘Read SFDP’ command 0x5A followed by three address bytes 0x00:3 and a dummy byte 0x00. Finally, read the 8 byte SFDP header r:8.

  • [0x5A 0x00:3 0x00 r:8] - Read the SFDP header.

The first four bytes of the response are the SFDP signature (0x53 0x46 0x44 0x50), so we now know the chip supports SFDP. If the response is all 0xff, the chip does not support SFDP.

ByteValueDescription
00x53‘S’
10x46‘F’
20x44‘D’
30x50‘P’
40x05Minor revision number
50x01Major revision number
60x00Number of parameter headers (+1)
70xFFEnd of parameter header

The next byte is the minor revision number (0x05), followed by the major revision number (0x01). This is a JEDEC v1.5 SFDP table. The number of parameter headers byte (0x00) plus 1 = 1 available Headers. The table ends with 0xFF.

Write 256 bytes

Finally, we can actually write some data to the chip. This is a multiple step process.

  1. Enable writes - The chip must be put into write mode before any write or erase commands will be accepted.
  2. Erase sector - A sector (4096 bytes) must be erased before writing.
  3. Enable writes - The chip must be put into write mode before any write or erase commands will be accepted.
  4. Write data page - Write a page of data (256 bytes) to the chip.
  5. Read data - Read the data back to verify it was written correctly.

Enable writes

The Write Enable instruction 0x06 must be sent before write and erase commands will be accepted. This prevents accidental erasures or overwrites of your valuable data.

  1. CS pin is pulled low
  2. Write the Write Enable instruction 0x06
  3. CS pin is pulled high
Bus Pirate [/dev/ttyS0]
SPI> [0x06]

CS Enabled
TX: 0x06 
CS Disabled
SPI> 
  • [ - Start of SPI transaction. Lowers the CS pin to ground.
  • 0x06 - Write Enable instruction.
  • ] - End of SPI transaction. Raises the CS pin to 3.3volts.

Verify write enable

The Read Status Register instruction 0x05 can be used to verify that the ‘Write Enable’ instruction was correctly received. The status register is a single byte that contains several flags.

  1. CS pin is pulled low
  2. Write the Read Status Register instruction 0x05
  3. Read the status register byte
  4. CS pin is pulled high
Bus Pirate [/dev/ttyS0]
SPI> [0x05 r]

CS Enabled
TX: 0x05 
RX: 0x02 
CS Disabled
SPI> 

Let’s read and decode the status register.

  • [ - Start of SPI transaction. Lowers the CS pin to ground.
  • 0x05 - Read Status Register instruction.
  • r - Read 1 byte.
  • ] - End of SPI transaction. Raises the CS pin to 3.3volts.

The status register value is 0x02.

Bus Pirate [/dev/ttyS0]
SPI> = 0x02
 =0x02 =2 =0b00000010
SPI> 

We can convert the status register value to binary to see which bits are set using the Bus Pirate = convert command.

We’re interested in bit S1, the write enable latch (WEL). WEL is set to 1 when the Write Enable instruction is received. WEL is 1 (0b00000010) so we’re ready to write some data!

Erase sector

Flash works by flipping 1s in the memory to 0. Writing a location twice will simply flip more bits from 1 to 0, but will not flip 0 to 1. The erase sector command 0x20 is used to flip all bits in a 4096 byte sector from 0 to 1, then we can write new data.

  1. CS pin is pulled low
  2. Write the Sector Erase instruction 0x20
  3. Write the 3 byte address of the first byte in the sector to erase
  4. CS pin is pulled high

The erase sector command is followed by a three byte address of the location to begin erasing 4096 bytes. It’s not possible to erase across sector boundaries. The 4096 byte sectors are ‘aligned’ in bocks. The first sector begins at 0, the next at 4096, the next at 8192 and so on.

Bus Pirate [/dev/ttyS0]
SPI> [0x06] [0x20 0x00 0x00 0x00]

CS Enabled
TX: 0x06 
CS Disabled
CS Enabled
TX: 0x20 0x00 0x00 0x00 
CS Disabled
SPI> 

We’ll erase the first sector from byte 0 to byte 4095. A write enable command must be sent before the erase sector command will be accepted.

  • [0x06] - Write Enable instruction (see Enable Writes).
  • [ - Start of SPI transaction. Lowers the CS pin to ground.
  • 0x20 - Erase Sector instruction.
  • 0x00 0x00 0x00 - Address 0x00.
  • ] - End of SPI transaction. Raises the CS pin to 3.3volts.

Verify erase sector

The Read Data instruction 0x03 can be used to verify that the sector has been erased. The read data command is followed by a three byte address where we’ll start reading.

  1. CS pin is pulled low
  2. Write the Read Data instruction 0x03
  3. Write the 3 byte address of the first byte to read
  4. Read data, up to the full size of the flash chip
  5. CS pin is pulled high
Bus Pirate [/dev/ttyS0]
SPI> [0x03 0x00 0x00 0x00 r:256]

CS Enabled
TX: 0x03 0x00 0x00 0x00 
RX: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 
    
CS Disabled
SPI> 

We’ll read the first 256 bytes from address 0x000000, all the bytes should be erased and set to 0xFF.

  • [ - Start of SPI transaction. Lowers the CS pin to ground.
  • 0x03 - Read Data instruction.
  • 0x00 0x00 0x00 - Start reading at address 0x000000.
  • r:256 - Read 256 bytes.
  • ] - End of SPI transaction. Raises the CS pin to 3.3volts.

The 256 bytes read are all 0xFF, the sector was successfully erased.

Enable writes and verify

Bus Pirate [/dev/ttyS0]
SPI> [0x06] [0x05 r]

CS Enabled
TX: 0x06 
CS Disabled
CS Enabled
TX: 0x05 
RX: 0x02 
CS Disabled
SPI> = 0x02
 =0x02 =2 =0b00000010
SPI> 

Use the write enable instruction 0x06 to enable writes. Verify the write enable bit is set to 1 (0x02=0b00000010) using the read status register instruction 0x05. We can do this all on a single line.

  • [0x06] [0x05 r] - Write Enable instruction followed by Read Status Register instruction. The response is the status register byte.
  • = 0x02 - Convert the status register value to binary. The write enable latch bit (0b00000010) should be set to 1.

Write data

The Page Program instruction 0x02 is used to write data to the flash chip. The smallest unit of data that can be written is a page, which is 256 bytes.

  1. CS pin is pulled low
  2. Write the Page Program instruction 0x02
  3. Write the 3 byte address of the first location to write
  4. Write 256 bytes of data
  5. CS pin is pulled high
Bus Pirate [/dev/ttyS0]
SPI> [0x06] [0x02 0x00 0x00 0x00 0xAA:256]

CS Enabled
TX: 0x06 
CS Disabled
CS Enabled
TX: 0x02 0x00 0x00 0x00 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 
CS Disabled
SPI> 

Use the page program command 0x02 to write 256 bytes of data to address 0x00. The command is followed by a three byte address of the location to begin writing 256 bytes 0x00 0x00 0x00. The data to be written i (0x69) follows the address.

  • [0x06] - Write Enable instruction (see Enable Writes).
  • [ - Start of SPI transaction. Lowers the CS pin to ground.
  • 0x02 - Page Program instruction.
  • 0x00 0x00 0x00 - Address to begin writing: 0x000000.
  • 0xAA:256 - Write 256 bytes of 0xAA.
  • ] - End of SPI transaction. Raises the CS pin to 3.3volts.

Read data

Bus Pirate [/dev/ttyS0]
SPI> [0x03 0x00 0x00 0x00 r:256]

CS Enabled
TX: 0x03 0x00 0x00 0x00 
RX: 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 0xAA 
    
CS Disabled
SPI> 

Use the Read Data instruction 0x03 once again to confirm the page was filled with 0xA0.

  • [ - Start of SPI transaction. Lowers the CS pin to ground.
  • 0x03 - Read Data instruction.
  • 0x00 0x00 0x00 - Address to begin reading: 0x00.
  • r:256 - Read 256 bytes of data.
  • ] - End of SPI transaction. Raises the CS pin to 3.3volts.

All 256 bytes read are 0xAA, the page was successfully written.

flash command

The flash command can read, write, and erase common SPI flash memory chips directly in the Bus Pirate terminal. The Serial Flash Universal Driver at the heart of the flash command attempts to identify the flash chip by reading the SFDP tables. If a chip doesn’t have SFDP tables, the driver has a database of common chips on which to fall back.

Bus Pirate [/dev/ttyS0]
SPI> flash init
Probing:
		Device ID	Manuf ID	Type ID		Capacity ID
RESID (0xAB)	0x13
REMSID (0x90)	0x13		0xef
RDID (0x9F)			0xef		0x40		0x14

Initializing SPI flash...
Flash device manufacturer ID 0xEF, type ID 0x40, capacity ID 0x14
SFDP V1.5, 0 parameter headers
		Type		Ver.	Length	Address
Table 0		JEDEC (0x00)	1.5	64B	0x000080
JEDEC basic flash parameter table info:
MSB-LSB  3    2    1    0
[0001] 0xFF 0xF1 0x20 0xE5
...
[0009] 0x00 0x00 0xD8 0x10
4 KB Erase is supported throughout the device (instruction 0x20)
Write granularity is 64 bytes or larger
Flash status register is non-volatile
3-Byte only addressing
Capacity is 1048576 Bytes
Flash device supports 4KB block erase (instruction 0x20)
Flash device supports 32KB block erase (instruction 0x52)
Flash device supports 64KB block erase (instruction 0xD8)
Found a Winbond  flash chip (1048576 bytes)
Flash device reset success

flash, flash init, and flash probe provide various levels of details about a flash chip. The flash command tries three common methods to identify a flash chip (RESID, REMSID, RDID), then attempts to read the SFDP tables.

Get a Bus Pirate

🛒

Get Bus Pirate & Accessories

Community