Go Down

Topic: New SPI EEPROM Library (Read 6223 times) previous topic - next topic

Wagner Sartori Junior

Jun 10, 2011, 08:36 pm Last Edit: Jun 11, 2011, 01:10 am by Wagner Sartori Junior Reason: 1
Hi,

I have developed a library to support SPI EEPROM IC's. I only have a 25LC1024 so it's the only one tested by now. It should support 16 and 24-bits memory addressing using the type parameter on class constructor. It's inspired/based on code by Heather Dewey-Hagborg available on http://www.arduino.cc/en/Tutorial/SPIEEPROM.

I wrote some documentation but it's far from completed.

Available on:
https://bitbucket.org/trunet/spieeprom/

Help is welcome.

KNOWN BUGS:
- You can write a char/byte array at this time but if the write command attempts to write across a physical page boundary, the result is that the data wraps around to the beginning of the current page

TODO:
- think on a way to deal with pages/page size

Thanks,

oscarcar

I couldn't find the part: 25LS1024

But from the other page I see you meant 25LC1024.

I don't have a need for it yet, but will certainly try yours out if I get there.

What's the major advantage of yours over the example in arduino? That it's more generalizable to all EEPROMs?

Wagner Sartori Junior

Typo... I corrected my post.

Some already implemented features and some planned:
- automatic conversion from int, long, float, ... to 1 or more bytes
- it checks if it already wrote on EEPROM using WIP(write in progress) register
- sequential read
- page write with protection to don't write across pages(it does not work and start overwriting)
- I'll try to make some kind of wear leveling on EEPROM. my suggestion is to use built-in address but it'll only work if the device is permanently on

copiertalk

do all manufacturers of eeproms use the same opcodes?

The eeprom I want to work with describes a 25 pulse wait, is this standard SPI or would that be eeprom independant for each manufacturer.

Thanks for the library and example code. It got me thinking. Nice article and structure. I like it.  :D

Wagner Sartori Junior

I don't know. As I said, I just have some 25LC1024.

I appreciate if you test it and if you have problems, try to open an issue on bitbucket with datasheet I can try to figured out what's happening and correct the library to work with some of them.

robtillaart


Quote
KNOWN BUGS:
- You can write a char/byte array at this time but if the write command attempts to write across a physical page boundary, the result is that the data wraps around to the beginning of the current page

TODO:
- think on a way to deal with pages/page size


Check my lib - http://arduino.cc/playground/Main/LibraryForI2CEEPROM - how I solved this same problem.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Wagner Sartori Junior


Check my lib - http://arduino.cc/playground/Main/LibraryForI2CEEPROM - how I solved this same problem.


What about we merge the library and make one that works with both I2C and SPI?

robtillaart


Could be done but I think 99% of the sketches using EEPROM use either I2C or SPI, not both. So merging the libs would unnecessary increase the footprint for both.

OK, you could merge and select the right  part using #ifdef's but that would not be userfriendly imho.

Think you just need to rewrite the private parts of the class to communicate blocks (of max BLOCKSIZE ) in SPI   - and remove the wire.begin() in the constructor

but feel free to give it a try ;)
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Wagner Sartori Junior

Tou're right. The footprint size will be a problem.

Maybe we can maintain as separated projects but with the same classes/methods.

I'll implement http://www.arduino.cc/playground/Code/EEPROMWriteAnything on my library, it'll return the size and the user can save float or struct variables directly. He only needs to know the address and size to calculate where to save next chunk of data instead of using tons of methods for each variable type.

robtillaart


In some of my spare time I've been thinking about another EEPROM library interface. (currently it is on the shelf as I have too much other things to do)

The idea is to create a linked list in the EEPROM of "allocated" memory. Each node is identified by a char[8]; when the node is created its size is defined and its location is determined.

Struct node
{
char[9] name;
uint16_t startPage;  // every chunck starts at page boundary so  - 1 - point to byte PAGESIZE (16/32?); this allows for max 64K nodes. 
uint16_t size;
uint16_t addressOfNextNode;
uint8_t deleted;  // flag that this chunk is freed.
}
The first node would be on address 0 of course.

If I get this working I can write something like

bool succes;
succes = readEEPROM("myappcnf", (void*) &myconfig);
succes = readEEPROM("lutclr", (void*) &lookUpTableRGB2CMYK);

and something like

succes = createEEPROM("GagaMidi", 1024);                          // create a node and a internal ref to a chunk of 1024 bytes
succes = WriteEEPROM("GagagMidi", (void*) &midiArray);     // and copy midiArray in it

If another sketch wants to use EEPROM it will never overwrite used EEPROM ... (never say never :)

what do you think of this idea?





Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

retrolefty

Quote
what do you think of this idea?


Cool, sounds like a basic database structure/access. Would it have to 'know' what avr processor is being used to determine eeprom max size so as to not wrap around ?

Lefty


robtillaart

Quote
Would it have to 'know' what avr processor is being used to determine eeprom max size so as to not wrap around ?


Yep it needs to know the EEPROM size, both  internal and external EEPROM. I was thinking that the library could determine this and allocate the first node with EEPROMsize info and a signature that the EEPROM is "formatted"

in pseudocode
Code: [Select]

if ( signature available)
{
  size = read EEPROMzsize from first block.
}
else
{
   size = determineSize();
   write size and signature to first block;
}

determineSize()
{
  write 0xFF to address 0x00;
  unsigned long i;
  for (i = 1; i< MAXLONG; i<<1)
  {
     write 0xAA to address i;                // assume addresses are multiples of 2..
     if (address 0x00 == 0xFF)  break;  // address 00 will eventually be overwritten by AA
  }
  if i<MAXLONG  return i;
  return 0xFFFFFFFFF;
}

 
 
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

#12
Aug 29, 2011, 04:40 am Last Edit: Aug 29, 2011, 04:45 am by spirilis Reason: 1
Hmm, I just banged out a library this weekend (called SPIEEP) to interface with the 25LC512 chip, might take a look at this one and see if I can merge it.  I did solve the problem of writing across page boundaries (a loop that divides & conquers the write or read) in my implementation, also wrote a cool "test_chip()" method that puts it through its paces (including deep-sleep mode & wakeup).  Mine only deals with byte's and byte-arrays though, which does makes things simple enough for page-boundary calculations/etc.

Here's my current version: http://spirilis.net/stuff/arduino/SPIEEP.zip

#13
Aug 29, 2011, 05:16 am Last Edit: Aug 29, 2011, 05:18 am by spirilis Reason: 1
FWIW, sounds like Microchip's 25****** lineup all use the same instruction set, although lower-capacity chips don't seem to have some of the fancier features such as deep-sleep, return-from-deep-sleep (so my test_chip() function would fail) and chip erase, page-erase, segment-erase and such.  But the read/write functions should work identically assuming you initialize the library with the right page-size 'n stuff.

256Kbit (32KB) example: http://www.mouser.com/ProductDetail/Microchip-Technology/25AA256-I-P/?qs=sGAEpiMZZMuVhdAcoizlRQmfcE3zL6VtaRPJnBU30sc%3d

Ooh actually found my first exception: http://www.mouser.com/ProductDetail/Microchip-Technology/25LC040A-I-P/?qs=sGAEpiMZZMuVhdAcoizlRSetfYkAy0SVR0ltHS3iTmA%3d
This is a 512-byte EEPROM, and the 9th bit of the address is embedded in the instruction, then it uses an 8-bit address.  That would take some code exceptions.  Basic instructions are the same, I guess the class would need a flag indicating whether part of the address stays inside the instruction and test that flag/compute the proper instruction code before submitting it.

Looks like that 4Kbit (512 byte) EEPROM is the only exception, as their 8+ Kbit units all use 16-bit addresses until you exceed 512Kbit (64KB).  That should be easy to catch/make exception.

Go Up