You are viewing an older revision! See the latest version

W25X40BV

Table of Contents

  1. API
  2. Source Code

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 that 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.

You can import the this published library at W25X40BV API.

I am in no way affiliated with digikey or windbond.

Import programSPIFlashW25X40BV

Simple test program for the W25X40BV API. The library files can be found in the next column or [[http://mbed.org/users/jyam/libraries/W25X40BV/m73pwt|here]].

API

Public Member Functions

/media/uploads/jyam/windbond_spi_flash_api.jpg

Source Code

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;
}


All wikipages