Winbond SPIFlash Writing - Reading Issue

Hello,
I’m using Winbond W25Q32 SPI Flash IC for data logging in my project.

I’m facing issue while writing multiple data to various address. I’m writing string to 3 different address and trying to read string from that locations. But I’m getting unpredictable output.

Arduino Uno
SPIFlash Library
Winbond W25Q32FVSSIG

Serial Monitor Output :

Initializing SPI Flash…
Chip Diagnostics initiated.

No Chip size defined by user
Man-ID: 61205
JEDEC-ID: 15679510
Capacity: 4194304
Max Page: 16384
STR:String 3
STR:tring 3
STR:tring 3

Below I have attached the code :

#include<SPI.h>
#include<SPIFlash.h>

SPIFlash flash(10);

unsigned int id;

void setup() 
{
  Serial.begin(9600);
  delay(10);

  Serial.println(F("Initializing SPI Flash..."));
  flash.begin();
  delay(500);

  id = flash.getManID();
  Serial.print(F("Man-ID: "));
  Serial.println(id);

  Serial.print(F("JEDEC-ID: "));
  Serial.println(flash.getJEDECID());  
  
  Serial.print(F("Capacity: "));
  Serial.println(flash.getCapacity());

  Serial.print(F("Max Page: "));
  Serial.println(flash.getMaxPage());

  String write_str = "String 1";
  flash.eraseSector(0);
  
  flash.writeStr(0, write_str, 1);
  write_str = "String 2";
  flash.writeStr(25, write_str, 1);
  write_str = "String 3";
  flash.writeStr(50, write_str, 1);
  
  String read_str = "";
  if(flash.readStr(0, read_str))
  {
    Serial.println("STR:" + read_str);  
  }
  else
  {
    Serial.println("Error");
  }
  read_str = "";
  if(flash.readStr(25, read_str))
  {
    Serial.println("STR:" + read_str);
  }
  else
  {
    Serial.println("Error");
  }
  read_str = "";
  if(flash.readStr(50, read_str))
  {
    Serial.println("STR:" + read_str);
  }
  else
  {
    Serial.println("Error");
  }
}

void loop() {
  // put your main code here, to run repeatedly:

}

That's weird and shouldn't be happening.

Quick questions:

  • Which version of the library are you using?
  • What board/µC are you using?

Thanks for providing the code you use. I'll test it out first thing this evening.

I’ve tested your code and it does not work - as you reported. I took a logic analyser to it and found that the problem is not with the library.

The writeStr function takes some time to write a string to the flash memory chip. After it is done writing - if successful - it returns a boolean 1 (True).

Your µC can cycle through commands faster than the SPI comms with the flash chip happen (in most cases SPI_CLK = System Clock/4). So, your code is forcing the µC to try and establish SPI comms with the flash chip to write the second string while the first is still being written and, the third while the second is still being written and so forth.

The reads have the same problem.

I’ve included some example code below that does not cause this problem. Hope this helps :slight_smile:

#include<SPIFlash.h>

uint32_t strAddr;

#if defined(ARDUINO_SAMD_ZERO) && defined(SERIAL_PORT_USBVIRTUAL)
// Required for Serial on Zero based boards
#define Serial SERIAL_PORT_USBVIRTUAL
#endif

#if defined (SIMBLEE)
#define BAUD_RATE 250000
#define RANDPIN 1
#else
#define BAUD_RATE 115200
#define RANDPIN A0
#endif

//SPIFlash flash(SS1, &SPI1);       //Use this constructor if using an SPI bus other than the default SPI. Only works with chips with more than one hardware SPI bus
SPIFlash flash;

bool readSerialStr(String &inputStr);

void setup() {
  Serial.begin(BAUD_RATE);
#if defined (ARDUINO_SAMD_ZERO) || (__AVR_ATmega32U4__)
  while (!Serial) ; // Wait for Serial monitor to open
#endif

  flash.begin();

  randomSeed(analogRead(RANDPIN));
  for (uint8_t i = 0; i < 3; i++) {
    Serial.print("Run no. :");
    Serial.println(i+1);
    strAddr = random(0, flash.getCapacity());
    String inputString = "This is a test String";
    flash.writeStr(strAddr, inputString);
    Serial.print(F("Written string: "));
    Serial.println(inputString);
    Serial.print(F("To address: "));
    Serial.println(strAddr);
    String outputString = "";
    if (flash.readStr(strAddr, outputString)) {
      Serial.print(F("Read string: "));
      Serial.println(outputString);
      Serial.print(F("From address: "));
      Serial.println(strAddr);
      Serial.println();
    }
    while (!flash.eraseSector(strAddr)) {};
  }
}

void loop() {

}