Go Down

Topic: SPIMemory library - Formerly SPIFlash - now supports basic SFDP! (Read 50035 times) previous topic - next topic


I am writing a code for w25q16bv flash memory. it had commands to erase the data upto 4Kb, sector erase upto 64Kb and total chip erase. but I only need to erase 256 bytes in a specified location. i tried writing 0xFF by using SPI.transfer(); function but no use. is there any way to resolve this problem?


You cannot write 0xFF to locations that already have data in them - they need to be erased properly.

The only way for you to erase a memory section that is smaller than 4KB would be to use a buffer. Roughly speaking, your code should do the following:

  • Figure out which 4KB block contains the 256 bytes that you need erased.
  • Copy the data in the whole of the block over to another vacant block and during this process, set the 256 bytes that you want to erase to 0xFF - or if your microcontroller has enough RAM, just hold the entire 4KB in the RAM as a byte array
  • Erase the 4KB block on the flash memory (containing the 256 bytes you need erased)
  • Write the byte array you have put aside in step 2, back to the newly erased 4KB sector on your flash memory

Et voilĂ ! The 256 bytes you want to erase will have been erased.  ;D


Just pushed an update through to v3.2.0 with the following changes:

- The Library is now called SPIMemory, not SPIFlash. The reason for this change can be found here.

- The library now gathers sfdp information through _chipID(). SFDP information is collected when available, otherwise the library defaults to using code from v3.1.0 to ID the chip.
- The library now does the following - if the flash memory chip is compatible with the SFDP standard
  - Identifies the flash memory chip using the Serial Flash Discoverable Parameters standard. (JESD216B)
  - Identifies the following opcodes from the SFDP tables and uses them to read/write data:
         - eraseSector, eraseBlock32K, eraseBlock64K
  - Reads timing information from SFDP to accurately time the following operations:
         - eraseSector, eraseBlock32K, eraseBlock64K

New flash memory chips supported:
- All flash memories compatible with the SFDP standard (as at JESD216B) should be compatible with the library

- LE25U40CMC from ON Semiconductor
- A25L512A0 from AMIC
- M25P40 from Micron
- AT25SF041 from Adesto
- S25FL032P from Cypress/Spansion

New Microcontrollers supported:
- ATSAMD51J19 ARM Cortex M4 (Adafruit Metro M4)

I've started work on proper documentation. As polaroi8d pointed out here, the old ReadMe was getting far too unwieldy and the Github Wiki is not the easiest thing to poke around. By the time the next release rolls around I hope to have the documentation done - (Rst + Sphinx). Check out the progress of the documentation here! Any recommendations are welcome  8)


Hi Marzogh

Did you received your JV series.
I am using W25Q64JV and i updated the library 3.2.0.
But library gives Error code: 0x0B


Hi mate,

Thanks for the heads up. I've got some JV series coming in from AliExpress, but this being AliExpress, they're probably a month or so away form getting to me in Australia. :/

I'll see if I can figure out what's going wrong (in theory) by looking at the timing on the datasheet and get back to you as soon as I can.

The current release version is v3.0.1 and that's what is available from the library manager. I'm still testing v3.1.0 is all platforms that library supports and should hopefully have it out before this week ends.

Feel free to pull down a zip of the development branch to test with your hardware. The code is pretty much good to go and just needs some battle testing before I sign off on a release.

If you are looking at using filesystems, Adafruit's SPI Flash library has quite good filesystem support with the ability to mount the chip up as a mass storage device. However, this is something I've only ever played around with on the M0 Express line of boards and I don't know how it works (or if it does) outside of the M0 / SAMD21 line.

I would like to - someday incorporate a filesystem into my library, but I have two problems with that:

  • I have no idea how filesystems work, much less how to implement one on the Arduino platform :P
  • My main aim with this library has been to get it to work as fast as it can while maintaining read/write integrity. AFAIK, putting a filesystem in there reduces this speed enormously.

I use the library with my environmental sensor units as a way of storing lots of data as (byte arrays) on an SPI Flash chip. When it fills up I write all of that data to an SD card in one go. This saves a ton of power when you have a low-power environmental sensing / logging system deployed in remote areas for extended periods of time. I borrowed this idea from EKMallon's fantastic Cave Pearl project. He uses EEPROMs to buffer data but I've found that using SPI Flash in combination with an SD card works equally well - especially when I use a TPL5110 timer to cut power to the entire system when it doesn't need to be operational. :)


Hi Ergun,

As I replied on your bug report on Github, I have received my W25Q64JV and tested it with v3.1.0 & with v3.2.0 and they work fine - no errors thrown at all. Could you please respond to my reply there?


Just pushed an update through to v3.2.1 with the following changes:

Bugs squashed:
- Fixes issue #135 : The addition of the SFDP checking to _chipID resulted in a sudden (very large) increase in compiled code size. As of the current version (v3.2.1), SFDP checking is an user controlled option. To get the library to work with SFDP compatible flash memory (that might not be officially supported), the user must uncomment '//#define USES_SFDP' in 'SPIMemory.h'.

- Moved bool _loopedOver from being a local variable in getAddress() to a global one. Now it actually does what it was meant to do - i.e. prevent looping over data a second time.

- As of v3.2.1, SFDP parameter discovery is an user controlled option. To get the library to work with SFDP compatible flash memory chips that are not officially supported by the library, the user must uncomment '//#define USES_SFDP' in 'SPIMemory.h'.
- The way the basic functions execute has been modified to keep the function runtime the same (or improved) while reducing their memory footprint.

Test sketch - FlashDiagnostics.ino from v3.2.0 with #RUNDIAGNOSTIC commented out
Test platform - Arduino Pro Mini 8MHz 3.3V

Library versionCompiled code sizeSFDP discovery% Difference from v3.1.0
v3.1.017652 bytesNot supported0%
v3.2.020104 bytesSupported & enabled by default+13.9%
v3.2.117854 bytesSupported & enabled+1.1%
v3.2.115316 bytesSupported & disabled-13.75%


(Low-priority / Feature request)

Not sure if this has been entertained before and dismissed for some reason, but:  It would be cool if the library API explicitly supported sequential access.  E.g. readNextByte() or similar.  It seems that most (all?) of these devices auto-increment addresses following accesses, meaning that they're optimized for sequential access.  Meanwhile, the library steers you toward random access, which is kind of worst-case scenario.  Supporting random access is fine, of course, but supporting and documenting the access pattern that the hardware is actually designed for seems important too.  Otherwise, people who need to stream bytes from memory are going to do things like readByte(addr++) and be severely punished for it when the library does 4x as many transfers as necessary.

Go Up