SPIMemory library - Formerly SPIFlash - now supports SPI FRAM as well! :)

Its finally here!!! Just pushed through an update to v3.0.0. This update is a major overhaul of the library and brings with it support for more flash memory manufacturers, more µC platforms, squashes a major bug, loses ATTiny85 support, and has a large number of optimizations for speed, stability & ease of development.

Bugs Squashed - The writeByteArray() & writeCharArray() bug that occurred when writing arrays that spanned page boundaries (squashed in v2.5.0), stayed around to haunt the other functions. Writing any data larger than a single byte that spanned page boundaries would cause the data to wrap around to the beginning of the page. The likelihood of this occurring was slim - no one has reported it to date. However, just in case, this has now been squashed in this release.

Deletions - Going forward the ATTiny85 is no longer officially supported. - The library no longer supports using the page number + offset combination instead of addresses. If your code requires you to use a page number + offset combination, use the following pseudocode to help

address = ( pagenumber << 8 ) + offset;

New Boards supported - Nucleo-F091RC - Adafruit Feather M0 - Adafruit Feather M0 Express (On board flash and external flash)

Flash memory chips supported - Winbond (All SPI Flash chips) - Microchip (SST25 & SST26 series) - Cypress/Spansion (S25FL series)

Enhancements & Optimizations - Confirmed to work with SPANSION/CYPRESS & MICROCHIP (Both SST25 & SST26 series). - If not using an officially supported chip, use the following variation of flash.begin() (where flashChipSize is indicated in Bytes, Kilobytes or Megabytes. (Refer to the next two items in this change log): flash.begin(flashChipSize); - Including 'flashChipSize' in flash.begin() compiles more efficiently than in previous versions. - The way memory size is indicated by the users in flash.begin(flashChipSize) has changed - please refer to defines.h or the wiki for further information. The new method enables users to define any custom size unlike the previous version where only a limited number of predetermined sizes were available to use. - Library faster than before (Refer to release notes for details) - Constructor changed to enable user to choose one of multiple SPI ports - if available. Look at wiki for further info - When RUNDIAGNOSTIC is uncommented in SPIFlash.h, users now have access to a new function called flash.functionRunTime() which can be called after any library I/O function is run. flash.functionRunTime() returns the time taken by the previous function to run, in microseconds (as a float). An example use case can be found when the FlashDiagnostics sketch is run with RUNDIAGNOSTIC uncommented. - _notBusy() is faster - Completely re-written FlashDiagnostics - uses fewer resources, compatible with more chips and boards - All functions except the Byte/Char Array Read/Write functions now call an internal _write/_read function for increased ease of compilation, execution and troubleshooting - Restructured the internal _troubleshoot() function to be better human readable and faster to compile. - Added a function getUniqueID() which returns the unique ID of the flash memory chip as a 64-bit integer. - Added an internal _readStat3() function to enable 4-byte addressing when using flash memory larger than 128 MB - 4-byte addressing enabled in flash memory larger than 128 MB. This is currently only supported on the W25Q256 and W25Q512. More chips will be supported on a case-by-case basis - getAddress() function now works anytime it is called - even if there is preexisting data on the chip

As always, you can find this version on Github here --> SPIFlash Library for Arduino v3.0.0 A ZIP file is also attached to the first post on this thread. The easiest way, as always, is to open up Library Manager on your Arduino IDE and update the libary to v3.0.0 :)

Is the Arduino Nano known to not work, or is it a matter of testing?

@liolau: The Nano is just a matter of testing. It uses the same ATMega328 µC as in the Uno so it should work with no issues.

Hi all, just pushed through a major bug-fix release v3.0.1

@hanyazou identified a major bug (detailed here in issue 102) which has been fixed with v3.0.1

v3.0.1 also adds support for the S25FL127S from Spansion/Cypress.

As always, you can find this version on Github here --> SPIFlash Library for Arduino v3.0.1 A ZIP file is also attached to the first post on this thread. The easiest way, as always, is to open up Library Manager on your Arduino IDE and update the library to v3.0.1 :)

Hi,

Does this library support QSPI ? I have wired W25Q128JV in QSPI mode and was wondering if I could try that with this llibrary

Hi, I get some error on save to flash. flash.writeAnything with char variables in struct fails.

I have two structs

struct Configuration {
  uint8_t tempHigh;         // store higher value for temperature
  uint8_t tempLow;          // store lower value for temperature
  bool parkingMode;         // store Parking Battery value boolean
  uint8_t chargingRange;    // store charging range status
  uint8_t chargingHigh;     // store charging higher value
  uint8_t chargingLow;      // store charging lower value
  boolean sendData;         // store send data flag
} configuration;

struct NetworkConfig {
  char ssid[50];            // Store network ssid from client
  char pwd[50];             // Store network password from client
  char userid[50];          // Store identification ID from client
} networkConfig;

set some values on both struct, and save to flash:

  Serial.print(">");
  Serial.print(networkConfig.ssid);
  Serial.println("<");
  Serial.print(">");
  Serial.print(networkConfig.pwd);
  Serial.println("<");
  Serial.print(">");
  Serial.print(networkConfig.userid);
  Serial.println("<");
  
  flash.eraseSector(0);
  if (flash.writeAnything(0, configuration)) {
    Serial.println ("Data write successful");
  } else {
    Serial.println ("Data write failed");
  }

  if (flash.writeAnything(1, networkConfig)) {
    Serial.println ("Data write successful");
  } else {
    Serial.println ("Data write failed");
  }
  flash.readAnything(0, configuration);
  flash.readAnything(1, networkConfig);

  Serial.println(networkConfig.ssid);
  Serial.println(networkConfig.pwd);
  Serial.println(networkConfig.userid);

Serial Monitor:

MYSSID< thePassword< 599bcc60e4942d4469d1c961< Data write successful Data write failed ⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮$⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮ ⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮$⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮ ⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮$⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮

All the values from struct "configuration" are OK. Some has an Idea please.

after changing struct to nested struct, all is good.

Hi - thanks for a fantastic library! I know this is a pretty big ask but maybe someone here can help out. I’d love to use this library on an STM32 MCU in the Particle ecosystem. Particle is a fork of Arduino/Wiring, in my understanding, so I don’t think a ton would need to change but it’s hard to tell. Has anyone tried this or perhaps have any advice for where I could start? Thank you!

Hi,
is there a conflict between EEPROM (mega2560 internal flash) and SPIFLASH Lib?
I tried to adjust the bootloader, then I noticed that the data on the winbond is gone, and the bootloader is not working as expected.

I tried this one.

Any idea?

@a7ashh14: I'm afraid it does not yet support QSPI. What µC are you using with your W25Q128JV?

@supscientist: I've yet to play around with the Particle/Electron ecosystem. Feel free to play around with the code in the 'stable' branch of the library on Github and see if you can make it compatible with the Particle ecosystem. :)

@mysource: What pins are you connecting your Flash memory to? I don't think that the conflict is between the EEPROM and the Flash - its the probably because you use the SPI bus to program your Mega. If somehow, during the programming the Slave Select pin (that you have your flash connected to) is a) pulled low or b) the voltage drops and the µC enters Brown-out mode - then the data that's being sent into your Mega might a) get piped into your Flash memory as well or b) be interrupted unexpectedly. This could very easily cause corruption of the data on both the Mega's internal flash and the external SPI Flash you are using.

@supscientist As a place to start, take a look at how Particle’s SPI Library works and see how you can replace the calls to the Arduino SPI Library with calls to the Particle SPI Library in FLASHIO.cpp. Every function in SPIFlash is built on top of the private functions in FLASHIO.cpp that make calls to the SPI Library - so the majority of your work should be done with this step. You might also have to modify some defines in defines.h.

Hi Marzogh,

Thanks for creating SPIFlash -- I can see a tremendous amount of work has gone into it.

I am new to SPI Flash memory so I may be asking a stupid question but here goes. My basic question is: does SPIFlash support the "JV" series of chips from Winbond, specifically the W25Q32JVSSIQ and W25Q64JVSSIQ? Or is there something about the JV series that makes them incompatible, and I should try to find the BV of FV series mentioned in the wiki?

The details:

I got some Winbond chips from DigiKey: W25Q32JVSSIQ and W25Q64JVSSIQ. I soldered them on some SMT breakout boards from Adafruit and wired them up to an Adafruit Feather M0. The pinouts are:

3V --> 8 (VCC) GND --> 4 (GND) SCK --> 6 (CLK) MOSI --> 5 (DI / IO0) MISO --> 2 (DO / IO1) GPIO #11 --> 1 (/CS)

At first, I did not hook up pins 3 (IO2) or 7 (IO3) to anything since it seemed they were not needed in this configuration.

I modified the readWriteString example sketch to tell it to use pin 11 for chip select in the SPIFlash constructor:

//SPIFlash flash;
SPIFlash flash(11);

However, when I run I get an endless stream of this error message:

Unable to Enable Writing to chip.
Please make sure the HOLD & WRITEPROTECT pins are pulled up to VCC

According to the Winbond data sheet, the JV series of chips do not have HOLD and WRITEPROTECT pins:

https://www.winbond.com/resource-files/w25q32jv%20spi%20revc%2008302016.pdf

Unlike the FV series, which state that pin 3 is both /WP and IO2, and pin 7 is both HOLD and IO3, the JV series just calls them IO2 and IO3. Looks like write protection is enabled/disabled only via the status registers.

I tried various combinations of tying pins 3 and/or 7 to Vdd and Vcc, but always got the same error. Then, based on the error message, I tried putting pullup resistors between 3 and 7 and Vcc, with values of 5.1K and then 100K, but I admit I'm just guessing there. Same result.

So ... am I out of luck? Is this chip series not supported?

Should I add pullup resistors between pins 3 and/or 7 to Vcc? If so, any suggestion on what values?

Thanks!

Hi ManlyEchidna, I'm afraid I have not tested the JV series of flash memory with the library. I've just quickly glanced over the datasheet you've linked to and I don't see any reason why they shouldn't work. The Error message that you are getting is only meant for chips with HOLD or WP pins, so, if you don't have them, you can ignore it.

Could you please run the following steps and let me know what output you get?

  • Make sure #define RUNDIAGNOSTIC is uncommented in your SPIFlash.h file and save it.
  • Upload the Diagnostics.ino sketch to your Feather M0 after setting
SPIFlash flash(11);
  • Paste the serial output from the sketch in your reply.

Let's see if we can get the library working with your chips :)

Hey there! I'm having a hard time getting SPIFlash to work with a Spansion S25FL127S (MCU is an ATMega328p with Uno bootloader running at 16 MHz, 3.3v). I keep getting various errors, including 0x0B and 0x06; I suspect a wiring issue, however everything seems OK. Power and ground are OK, SPI lines are correct, CS is pulled high with a 10kohm resistor, and write protect and hold are both tied high. Any idea what's going wrong? Other devices on that same SPI bus work fine. (SPIFlash still errors out even with nothing else on the SPI bus.)

@compucat have you tried removing the pull up on the CS pin?

Yup, I've tried with CS pulled up, no pullup, write protect and hold floating, tied high, tied low. Nothing seems to work. Only change I've made to the FlashDiagnostics code is to set an alternative CS pin. Do you have a working schematic for an ATMega328p+Spansion setup?

EDIT: I've also tried wiring it to a stock Arduino Uno with resistors as level shifters, no dice. I might try again with a fresh chip just to rule out bad silicon.

EDIT 2: Tried a fresh chip, no dice.

Hi I am trying to use this library to access an LC W25Q80B memory modules with a Winbond 25Q80 from a BluePill STM32F103. http://www.chinalctech.com/index.php?_m=mod_product&_a=view&p_id=1066 It looks like a great library but I cant get anything from the FlashDiagnostics example. Reading the instructions I should remove the // from #define RUNDIAGNOSTIC in SPIFlash.cpp but I cant find it there but it is in the SPIFlash.h but it is already un-commented so I leave everything as is. The examples builds and runs on the STM but I only get the following output:

Initialising Flash memory..........
Chip Diagnostics initiated.

No Chip size defined by user



--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
                                                                    SPIFlash Library version: 3.0.0
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
                                                                                Get ID
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
...JEDEC ID: ef4014h

If I connect using Arduino Pro Mini 3.3, I get:

Opening port
Port open
Initialising Flash memory..........
Chip Diagnostics initiated.

No Chip size defined by user



--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
                                                                    SPIFlash Library version: 3.0.0
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
                                                                                Get ID
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
            JEDEC ID: ef4014h
            Manufacturer ID: efh
            Memory Type: 40h
            Capacity: 1048576 bytes
            Maximum pages: 4096
            Unique ID: 1153678118893824, 0x608414039E763900
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

            Erase Chip:         Data I/O test PASS          Time: 1.274 s
            Erase 64KB Block:   Data I/O test PASS          Time: 128.920 ms
            Erase 32KB Block:   Data I/O test PASS          Time: 109.400 ms
            Erase 4KB Sector:   Data I/O test PASS          Time: 42.328 ms

            Byte:           Data I/O test PASS          Write Time: 320 us, Read Time: 128 us
            Char:           Data I/O test PASS          Write Time: 328 us, Read Time: 128 us
            Word:           Data I/O test PASS          Write Time: 352 us, Read Time: 128 us
            Short:          Data I/O test PASS          Write Time: 360 us, Read Time: 128 us
            ULong:          Data I/O test PASS          Write Time: 384 us, Read Time: 136 us
            Long:           Data I/O test PASS          Write Time: 376 us, Read Time: 144 us
Error code: 0x0A
            Float:          Data I/O test FAIL          Write Time: 0 us,   Read Time: 160 us
            Struct:         Data I/O test PASS          Write Time: 160 us, Read Time: 160 us
            Byte Array:         Data I/O test PASS          Write Time: 5.288 ms,   Read Time: 888 us
            String:         Data I/O test PASS          Write Time: 424 us, Read Time: 152 us
            Power Down:         Data I/O test FAIL          Not all chips support power down. Please check your datasheet.
            Power Up:       Data I/O test PASS          Time: 176 us
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Any suggestions please

Hi I am trying to use this library to access W25Q64JV with Arduino MEGA. But i coldn’t be successful.
W25Q64BV is obsolete and i used W25Q64JV.
Do you have any relevant ideas about this?

Thanks

W25Q64BV is obsolete? Hmmm... why do you think so?

I have a funny problem with this kind of memory. Namely, I can't find any sketch which demonstrates the simpliest read/write operations with W25 chips. Can someone help with this?

@ Compucat : I’m afraid I can’t explain why that’s happening with you. The library appears to work fine with the S25FL127S I have. I’ll try out a few other chips this weekend and let you know if I face any issues.

@ TrekRider: I’m afraid the library does not officially support the BluePill. I have had a lot of trouble getting the USB bootloader working on my boards and gave up just before Christmas. However, I’m still keen on supporting the board, so, could you do me a favour and raise an issue on the Github page [here]? I’ll get going started again on getting the Blue pill supported. :smiley:

@ kucukkose: Thanks for raising an issue on Github about this. Could you please refer to my comments there and provide a little more information on what exactly the problem seems to be?

@ Gosh: What do you mean by simple sketch to demonstrate read/write operations? Are you looking for code that works with the SPIFlash library or SPI level code?