Winbond W25Q128JV Flash Memory
Posted: December 25, 2020
SparkFun was selling a breakout board for the Winbond W25Q128JV 128Mbit flash memory chip, so I grabbed one to write some simple code for it incase I needed it sometime. I started out with a MSP430G2553 microcontroller but also wrote some code in Python for the Raspberry Pi. I posted all the code below incase anyone wants it. The MSP430 code assembles with naken_asm.
Here's a picture of the breakout board connected to a Raspberry Pi 4. Unfortunately I didn't have more colors for the 8 wires, but red/black are 3.3v and ground, blue is data in / out (MISO->DO, MOSI->DI), far left green is clock, yellow is chip select, the other green is winbond reset, and the other yellow is write protect.
I started with the MSP430G2553 code by copying the source code from an earlier MSP430 / Ethernet project. All the ethernet code was deleted and the Winbond code was added. The concept is pretty simple: for read / writes / erases, a 1 byte command code is passed along with 3 bytes in big endian format for address of the area affected. Before writing to an area, a sector (or block) erase has to be done first (setting all bytes in the area to 0xff). I believe writing to flash can only flip bits to 0 so if the sector erase is left out, the data written could look corrupted if any bits need to be changed from 0 to 1.
Data is sent to the chip over SPI with 2 extra signals: /RESET and /WP (write protect). I use the /RESET signal on both the RPI 4 and the MSP430 by setting it low, using a delay, and then setting it back high. I tried the system without connecting the reset pin and it didn't work, so it seems it is needed. /WP is set to low so that data can be written to flash.
For the Raspberry Pi code, I decided to use Python. The gpiozero and spidev modules are used for the I/O (reset, WP, and SPI chip select) and the SPI data. Calls to spi.xfer2() read / write data from Winbond chip. For example, to read 4 bytes from flash memory at address 0x000000, SPI is sent 8 bytes of 0x03 for the command "read from flash", 3 bytes of the address, and 4 bytes to hold the data returned back:
Since SPI reads and writes from the bus the same time, for every byte sent there is one byte returned. The first four bytes return 0 since the Winbond is reading in a command, but for the last 4 dummy bytes sent to the Winbond, it returns data starting at location 0:
The above data returned shows 77 (the letter M, since that's what I set earlier with the MSP430 code) and three 255's since those locations were unprogrammed. If I had wanted to read 2 bytes starting at address 0x000050, the SPI data sent would have been
Copyright 1997-2021 - Michael Kohn