You are viewing an older revision! See the latest version
W25X40BV
The is a simple read/write API for the Winbond W25X40BV SPI Flash IC (datasheet).
The W25X40BV IC is one of the few commercially available SPI Flash ICs comes in DIP packaging, ideal for those hobbyists who want to prototype flash memory without dealing with surface mount devices (SMD). This IC can be purchased from digikey.
This simple API does not utilize the performance benefits of sequential read/write or of the dual I/O SPI functionality provided by the IC.
W25X40BV.h¶
// W25X40BV.h
#ifndef W25X40BV_H
#define W25X40BV_H
#include "mbed.h"
#define SPI_FREQ 1000000
#define SPI_MODE 0
#define SPI_NBIT 8
#define WE_INST 0x06
#define WD_INST 0x04
#define R_INST 0x03
#define W_INST 0x02
#define C_ERASE_INST 0x60
#define DUMMY_ADDR 0x00
#define WAIT_TIME 1
#define ADDR_BMASK2 0x00ff0000
#define ADDR_BMASK1 0x0000ff00
#define ADDR_BMASK0 0x000000ff
#define ADDR_BSHIFT2 16
#define ADDR_BSHIFT1 8
#define ADDR_BSHIFT0 0
class W25X40BV {
public:
W25X40BV(PinName mosi, PinName miso, PinName sclk, PinName cs);
int read(int addr); // takes a 24-bit (3 bytes) address and returns the data (1 byte) at that location
int read(int a2, int a1, int a0); // takes the address in 3 separate bytes A[23,16], A[15,8], A[7,0]
void write(int addr, int data); // takes a 24-bit (3 bytes) address and a byte of data to write at that location
void write(int a2, int a1, int a0, int data); // takes the address in 3 separate bytes A[23,16], A[15,8], A[7,0]
void chipErase(); // erase all data on chip
private:
void writeEnable(); // write enable
void writeDisable(); // write disable
void chipEnable(); // chip enable
void chipDisable(); // chip disable
SPI _spi;
DigitalOut _cs;
};
#endif
W25X40BV.cpp¶
// W25X40BV.cpp
#include"W25X40BV.h"
// CONSTRUCTOR
W25X40BV::W25X40BV(PinName mosi, PinName miso, PinName sclk, PinName cs) : _spi(mosi, miso, sclk), _cs(cs) {
_spi.format(SPI_NBIT, SPI_MODE);
_spi.frequency(SPI_FREQ);
chipDisable();
}
// READING
int W25X40BV::read(int addr) {
chipEnable();
_spi.write(R_INST);
_spi.write((addr & ADDR_BMASK2) >> ADDR_BSHIFT2);
_spi.write((addr & ADDR_BMASK1) >> ADDR_BSHIFT1);
_spi.write((addr & ADDR_BMASK0) >> ADDR_BSHIFT0);
int response = _spi.write(DUMMY_ADDR);
chipDisable();
return response;
}
int W25X40BV::read(int a2, int a1, int a0) {
chipEnable();
_spi.write(R_INST);
_spi.write(a2);
_spi.write(a1);
_spi.write(a0);
int response = _spi.write(DUMMY_ADDR);
chipDisable();
return response;
}
// WRITING
void W25X40BV::write(int addr, int data) {
writeEnable();
chipEnable();
_spi.write(W_INST);
_spi.write((addr & ADDR_BMASK2) >> ADDR_BSHIFT2);
_spi.write((addr & ADDR_BMASK1) >> ADDR_BSHIFT1);
_spi.write((addr & ADDR_BMASK0) >> ADDR_BSHIFT0);
_spi.write(data);
chipDisable();
writeDisable();
wait(WAIT_TIME);
}
void W25X40BV::write(int a2, int a1, int a0, int data) {
writeEnable();
chipEnable();
_spi.write(W_INST);
_spi.write(a2);
_spi.write(a1);
_spi.write(a0);
_spi.write(data);
chipDisable();
writeDisable();
wait(WAIT_TIME);
}
//ERASING
void W25X40BV::chipErase() {
writeEnable();
chipEnable();
_spi.write(C_ERASE_INST);
chipDisable();
writeDisable();
wait(WAIT_TIME);
}
//ENABLE/DISABLE (private functions)
void W25X40BV::writeEnable() {
chipEnable();
_spi.write(WE_INST);
chipDisable();
}
void W25X40BV::writeDisable() {
chipEnable();
_spi.write(WD_INST);
chipDisable();
}
void W25X40BV::chipEnable() {
_cs = 0;
}
void W25X40BV::chipDisable() {
_cs = 1;
}
Example Usage (Main Function)¶
#include "mbed.h"
#include"W25X40BV.h"
Serial pc(USBTX, USBRX); // tx, rx
int main() {
W25X40BV flash(p5, p6, p7, p8);
pc.printf("SPI init done\n");
flash.chipErase();
pc.printf("Erase done\n");
pc.printf("%d\n", flash.read(0x00,0x00,0x06));
pc.printf("%d\n", flash.read(0x06));
flash.write(0x0, 0x0, 0x06,'a');
flash.write(0x11,'b');
pc.printf("%c\n", flash.read(0x06));
pc.printf("%c\n", flash.read(0x00,0x00,0x06));
pc.printf("%c\n", flash.read(0x11));
pc.printf("%c\n", flash.read(0x00,0x00,0x11));
return 0;
}