Arduino external Flash Library Write Struct - Page 1
Forum section: electronics / general

author: tomshirvo
author_rank: Regular Contributor
timestamp: November 11, 2014, 01:28:56 am
content: 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 EEPROMWriteAnythinghttp://playground.arduino.cc/Code/EEPROMWriteAnythingI 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.SketchCode:#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 OutputCode:Saving amount: 32215623123123.12Saved!Local Set to 0Reading back: 32After reading-51457-1nanflashMemory.h fileCode:#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"#endifclass flashMemory{public:flashMemory(uint8_t CE);flashMemory(uint8_t CE,uint8_t SPIClock);voidbegin();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;}#endifflashMemory.cpp fileCode: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 busSPI.transfer(0x06); //WREN (Write Enable)digitalWrite(_pinCE,HIGH); //deselect the Flash chip on the SPI buserror = verifySR(1,1);}while(error == false && millis() - time < _timeOut); //Retry until the change was madereturn 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 busSPI.transfer(0x04); ///WRDI (Write Disable)digitalWrite(_pinCE,HIGH); //deselect the Flash chip on the SPI buserror = verifySR(1,1);}while(error == false && millis() - time < _timeOut); //Retry until the change was madereturn error;}//Verify Status Register//Send the register location and the value you are expecting.//This will return a boolean for the resultboolean 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 busSPI.transfer(0x05); //Send the status register read instructionerror = SPI.transfer(0xff); //Read the returned data from the chipif(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 positionif(_value != value){ //return if it was the correct response or not.return false;}else if(_value == value){return true;}}

author: tomshirvo
author_rank: Regular Contributor
timestamp: November 11, 2014, 02:06:49 am
content: I found the problem and sorted it out.It would be nice if you could delete your own posts on this forum.

author: Marzogh
author_rank: Contributor
timestamp: June 22, 2015, 10:45:02 am
content: 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.

author: tomshirvo
author_rank: Regular Contributor
timestamp: June 22, 2015, 11:24:13 am
content: 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 anythinghttp://playground.arduino.cc/Code/EEPROMWriteAnything

author: Marzogh
author_rank: Contributor
timestamp: September 04, 2015, 11:08:16 am
content: 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 tohttp://www.github.com/Marzogh/SPIFlash.Cheers!