Library for Arduino Due & Serial Flash communication over SPI?

Hello,

I'm trying to connect a W25Q128FV Serial Flash (256 bytes/page) to the Arduino Due via the SPI interface. I was hoping that someone may have written a library for this already?

The SPI Flash library by LowPowerLab looked like a good candidate, but is uses Atmega specific registers, which won't work on the Due, such as SPCR and SPSR.

I am aware that the Due has a dedicated SPI port directly above the silkscreened ARDUINO DUE and figure 8.

If a library exists, it would sure save me a lot of time! If not, an example sketch would also be awesome.

Cheers,
Bret

Some puzzling commits in that repo. The maintainer merges a pull request, then the same day rips out all those changes and adds new stuff which breaks compatibility. :~

I suggest if you take the version at Merge pull request #3 from PaulStoffregen/master it will work ok on Due.

Thanks, that was definitely helpful. That code needed some minor updates to compile, but otherwise probably works fine. I couldn't get it to work, but it could have been my wiring.

Hmm. Unfortunately, I could not get the SPI Flash library by LowPowerLab to work for the Arduino Due. However, that code did help me out considerably. I've hacked together a working demo that writes and reads a byte to the W25Q128FV serial flash. I'm using pin 4 for the chip select:

#include <SPI.h>

#define SERIAL_BAUD 9600
#define MEMORY 4 // Chip select pin

#define SPI_FLASH_WRITE_ENABLE    0x06        // Write enable 
#define SPI_FLASH_READ_ID         0x90        // Manufacturer/Device ID
#define SPI_FLASH_SECTOR_ERASE    0x20        // Sector Erase
#define SPI_FLASH_PAGE_PROGRAM    0x02        // Page program
#define SPI_FLASH_READ_DATA       0x03        // Read Data
#define SPI_FLASH_READ_STATUS     0x05        // Read Status Register 1


void setup()
{
  Serial.begin(SERIAL_BAUD);
  Serial.println("Starting");

  SPI.begin(MEMORY);
  SPI.setClockDivider(MEMORY, 21);
  SPI.setDataMode(MEMORY, SPI_MODE0);

  // Get manufacturer id
  SPI.transfer(MEMORY, SPI_FLASH_READ_ID, SPI_CONTINUE);
  SPI.transfer(MEMORY, 0x00, SPI_CONTINUE);
  SPI.transfer(MEMORY, 0x00, SPI_CONTINUE);
  SPI.transfer(MEMORY, 0x00, SPI_CONTINUE);

  byte response1 = SPI.transfer(MEMORY, 0x00, SPI_CONTINUE);
  byte response2 = SPI.transfer(MEMORY, 0x00);

  Serial.print("Manufacturer ID: ");
  Serial.print(response1);
  Serial.print(", ");
  Serial.println(response2);

  long address = 123;

  // Erase some memory
  Serial.println("Erasing memory");
  SPI.transfer(MEMORY, SPI_FLASH_WRITE_ENABLE);
  SPI.transfer(MEMORY, SPI_FLASH_SECTOR_ERASE, SPI_CONTINUE);
  SPI.transfer(MEMORY, address >> 16, SPI_CONTINUE);
  SPI.transfer(MEMORY, address >> 8, SPI_CONTINUE);
  SPI.transfer(MEMORY, address);
  while(busy());  

  // Write some memory
  Serial.println("Writing memory");
  SPI.transfer(MEMORY, SPI_FLASH_WRITE_ENABLE);
  SPI.transfer(MEMORY, SPI_FLASH_PAGE_PROGRAM, SPI_CONTINUE);
  SPI.transfer(MEMORY, address >> 16, SPI_CONTINUE);
  SPI.transfer(MEMORY, address >> 8, SPI_CONTINUE);
  SPI.transfer(MEMORY, address, SPI_CONTINUE);
  SPI.transfer(MEMORY, 49); // Byte to transfer
  while(busy());

  // Read some memory
  Serial.println("Reading memory");
  SPI.transfer(MEMORY, SPI_FLASH_READ_DATA, SPI_CONTINUE);
  SPI.transfer(MEMORY, address >> 16, SPI_CONTINUE);
  SPI.transfer(MEMORY, address >> 8, SPI_CONTINUE);
  SPI.transfer(MEMORY, address, SPI_CONTINUE);
  byte result = SPI.transfer(MEMORY, 0x00);  

  Serial.print("Byte read: ");
  Serial.println(result);
}


void loop()
{
}

boolean busy()
{
  Serial.print("Status: ");
  SPI.transfer(MEMORY, SPI_FLASH_READ_STATUS, SPI_CONTINUE);
  byte status = SPI.transfer(MEMORY, 0x00);
  Serial.println(status);
  return(status & 1); // first bit of status register byte is "Erase/Write in progress" flag
}