Author Topic: Arduino external Flash Library Write Struct  (Read 5904 times)

0 Members and 1 Guest are viewing this topic.

Offline tomshirvoTopic starter

  • Regular Contributor
  • *
  • Posts: 53
Arduino external Flash Library Write Struct
« on: November 11, 2014, 01:28:56 am »
I am making a flash library for an external SPI flash chip attached to my Arduino Due.

I want to be able to store information on it like with the EEPROMWriteAnything http://playground.arduino.cc/Code/EEPROMWriteAnything

I am trying to store a struct on the Flash chip, below I have my sketch and library files. After trying to read back the data it gives me different values.

It has taken me a while just to get the library to compile with the templates as I have never used them before.

Sketch
Code: [Select]
#include <SPI.h>

#include <flashMemory.h>
flashMemory exFlash(7,4);

struct trackSettings
{
  long monkeys;
  int dogs;
  double cats;
  String mice;
} configuration;

void setup() {
  exFlash.begin();
  Serial.begin(115200);
  configuration.monkeys = 215623;
  configuration.dogs = 123;
  configuration.cats = 123.123;
}

void loop() {
  Serial.print("Saving amount: ");
  Serial.println(exFlash.writeAnything(0,configuration));
  Serial.println(configuration.monkeys);
  Serial.println(configuration.dogs);
  Serial.println(configuration.cats);
 
  Serial.println("Saved!");
  configuration.monkeys = 0;
  configuration.dogs = 0;
  configuration.cats = 0;
  Serial.println("Local Set to 0");
  Serial.print("Reading back: ");
  Serial.println(exFlash.readAnything(0,configuration));
 
  Serial.println("After reading");
  Serial.println(configuration.monkeys);
  Serial.println(configuration.dogs);
  Serial.println(configuration.cats);
 
  while(1){}
}

Serial Monitor Output
Code: [Select]
Saving amount: 32
215623
123
123.12
Saved!
Local Set to 0
Reading back: 32
After reading
-51457
-1
nan

flashMemory.h file
Code: [Select]
#ifndef flashMemory_h
#define flashMemory_h



#if defined(__AVR__)
#include "Arduino.h"
  #include "SPI.h"
#include "hardware/avr/HW_AVR_defines.h"
#elif defined(__arm__)
#include "Arduino.h"
  #include "SPI.h"
#include "hardware/arm/HW_ARM_defines.h"
#endif

class flashMemory
{
public:
    flashMemory(uint8_t CE);
    flashMemory(uint8_t CE,uint8_t SPIClock);
    void    begin();
    boolean    bulkErase();
    boolean    writeEnable();
    boolean    writeDisable();
    boolean    verifySR(uint8_t sRegister, uint8_t value);
    void       timeOut(uint16_t timeOut);
    uint16_t   timeOut();
    void       write(uint32_t address, uint16_t value);
    byte       read(uint32_t address);
    template <class T> uint16_t   writeAnything(uint16_t ee, const T& value);
    template <class T> uint16_t   readAnything(uint16_t ee, T& value);
  protected:
    uint8_t   _pinCE, _SPIClock; 
    uint16_t  _timeOut;
    boolean   _SPIClockSelect;
    void   _SPIstart(uint8_t rate);
    void      _writeFlash(uint32_t address, uint16_t value);
};

template <class T> uint16_t flashMemory::writeAnything(uint16_t ee, const T& value)
{
  const byte* p = (const byte*)(const void*)&value;
  uint16_t i;
  for(i = 0; i < sizeof(value);i++)
  {
    write(ee++,*p++);
  }
  return i;
}

template <class T> uint16_t flashMemory::readAnything(uint16_t ee, T& value)
{
  byte* p = (byte*)(void*)&value;
  uint16_t i;
  for(i = 0;i<sizeof(value);i++)
  {
    *p++ = read(ee++);
  }
  return i;
}

#endif

flashMemory.cpp file

Code: [Select]

boolean flashMemory::bulkErase()
{
  writeEnable();
  digitalWrite(_pinCE,LOW);
  SPI.transfer(0xC7);
  digitalWrite(_pinCE,HIGH);
  uint32_t start = millis();
  boolean error = false;
 
  while(error == true && millis() - start < _timeOut){
    error = verifySR(0,1);
  }
  return error;
}


void flashMemory::timeOut(uint16_t timeOut)
{
  _timeOut = timeOut;
}

uint16_t flashMemory::timeOut()
{
  return _timeOut;
}


//Write Enable
//This enables data to be send to the Flash chip to write data.
boolean flashMemory::writeEnable(void){
  uint32_t time = millis();
  boolean error = false;
  do{
    digitalWrite(_pinCE,LOW); //Select the Flash chip on the SPI bus
    SPI.transfer(0x06); //WREN (Write Enable)
    digitalWrite(_pinCE,HIGH); //deselect the Flash chip on the SPI bus
    error = verifySR(1,1);
  }while(error == false && millis() - time < _timeOut); //Retry until the change was made
  return error;
}

//Write Disable
//This disables data to be send to the Flash chip to write data.
boolean flashMemory::writeDisable(){
  uint32_t time = millis();
  boolean error = false;
  do{
    digitalWrite(_pinCE,LOW); //Select the Flash chip on the SPI bus
    SPI.transfer(0x04); ///WRDI (Write Disable)
    digitalWrite(_pinCE,HIGH); //deselect the Flash chip on the SPI bus
    error = verifySR(1,1);
  }while(error == false && millis() - time < _timeOut); //Retry until the change was made
  return error;
}

//Verify Status Register
//Send the register location and the value you are expecting.
//This will return a boolean for the result
boolean flashMemory::verifySR(byte sRegister, byte value){
  uint32_t time = millis();
  byte error = 0; //Hold the returned value from the status register.
  do{
    digitalWrite(_pinCE,LOW); //Select the Flash chip on the SPI bus
    SPI.transfer(0x05); //Send the status register read instruction
    error = SPI.transfer(0xff); //Read the returned data from the chip
    if(error == 255){ //If error code is 255 then show user in serial monitor

    }
    digitalWrite(_pinCE,HIGH); //deselect the Flash chip on the SPI bus
  }while(error == 255 && millis() - time < _timeOut); //do it once and if error do it until no error.
  byte _value = 0; //The value collected in the required register position
  _value = bitRead(error,sRegister); //get the value returned in that position
  if(_value != value){ //return if it was the correct response or not.
    return false;
  }else if(_value == value){
    return true;
  }
}
 

Offline tomshirvoTopic starter

  • Regular Contributor
  • *
  • Posts: 53
Re: Arduino external Flash Library Write Struct
« Reply #1 on: November 11, 2014, 02:06:49 am »
I found the problem and sorted it out.

It would be nice if you could delete your own posts on this forum.

 

Offline Marzogh

  • Contributor
  • Posts: 10
  • Country: au
Re: Arduino external Flash Library Write Struct
« Reply #2 on: June 22, 2015, 10:45:02 am »
Hi Tom,

I'm trying to solve the same problem with my library to write to external flash from an Arduino Uno. The Arduino pre-processor's issues with using structs in functions have made things hard. :( Could you explain how you got around your problem please?

Thanks in advance. :)
 

Offline tomshirvoTopic starter

  • Regular Contributor
  • *
  • Posts: 53
Re: Arduino external Flash Library Write Struct
« Reply #3 on: June 22, 2015, 11:24:13 am »
I used the code from the eeprom "write anything" library and copied it into my library I made for the flash chip that I am using. It seems to work well as we are using it in production now.

Look up "templates" this is what is used to take any variable and store it on the flash.

I can help but I'm not sure what you need help with. If you look up what I have said and learn what a "template" is you should be fine.

This is the link to write anything http://playground.arduino.cc/Code/EEPROMWriteAnything
 

Offline Marzogh

  • Contributor
  • Posts: 10
  • Country: au
Re: Arduino external Flash Library Write Struct
« Reply #4 on: September 04, 2015, 11:08:16 am »
Thanks for that mate. :)

Its all done and good to go. If you'd like to take a look at it, its available straight from the Arduino library manager - just search for SPIFlash or go directly to http://www.github.com/Marzogh/SPIFlash.

Cheers!
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf