Go Down

Topic: Library for Arduino Due & Serial Flash communication over SPI? (Read 1 time) previous topic - next topic

clone45

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

bobcousins

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.
Please ask questions in the forum so everyone can benefit. PM me for paid work.

clone45

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.

clone45

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:

Code: [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
}


Go Up