Class for interfacing Microchip 25LC/25AA series SPI serial EEPROM

I recently wrote a library to support a 25LC512 chip I bought and decided to go further and make it general-purpose enough to support the whole line of 25LC/25AA chips.
**Note: I have not physically tested any chips besides the 25LC512, in a near-future parts order I may buy a few of them to try them out.

Library is called SPIEEP
Documentation is here: https://bitbucket.org/spirilis/spieep/wiki/Home

Bitbucket repository: https://bitbucket.org/spirilis/spieep/src

Zip file of current version: http://spirilis.net/stuff/arduino/SPIEEP.zip

Key features/omissions:

Supports almost all features on the chips, including Deep Power Down mode and Chip, Page Erase for those chips that support it (25LC512 and 25LC1024, for the most part)

Does not manage the Write Protection or implement Segment Erase opcode

Supports writing/reading arbitrary lengths of data to/from the EEPROM in an efficient manner even if it spans page boundaries, and supports a companion set of functions that write/read other data types like int, long, float and double with addresses adjusted to reflect the multiple-byte nature of these datatypes.

Also includes "_offset" functions that allow you to read/write int, long, float, double with the address adjusted by a byte-level "origin" so you can, for instance, store an array of doubles (and reference them from 0 to 100, for example) but begin storing them at address 0x1FFE, rather than 0x0000 or whatever. Useful for partitioning an EEPROM chip into multiple arrays of different datatypes.

Includes a "test_chip()" method which destructively overwrites/reads the last byte on the chip; helpful to determine if your chip is functioning properly. This goes a step further on the 25LC512/25LC1024 to work out the Deep Power Down mode, verifying that reads aren't successful during deep-sleep.

Includes support for the 25LC040's quirky addressing, where it uses an 8-bit address but stuffs the 9th address bit inside the instruction opcode.

Main gripe I can admit is that I went overboard writing everything and the whole library feels a bit bloated for something intended for embedded computing :smiley: But it works fine on my ATmega8.

Hello spirilis,

great work you did on this library. I did some modifications on it for Arduino 1.0

First SPIEEP.h
line 33 changed to
include <Arduino.h>
About the Arduino team changed the filename

Second SPIEEP.ccp
line 58 changed to if (SPE) {
About it's enought to look at this if it 1 SPI is enabled

line 232 changed to for (i=_addrwidth; i>=0; i--)
About decreasing _addrwidth by 1, and the wrong address is choosen with a _addrwidth by 1 the loop never entered.

BR.

Markus

Thanks Markus... I'm not sure about the code changes to SPIEEP.cpp though, can you elaborate-

Second SPIEEP.ccp
line 58 changed to if (SPE) {
About it's enought to look at this if it 1 SPI is enabled

I thought "SPE" was just a constant indicating which bit represented the "SPI Enabled" register in the SPCR variable? So checking if (SPE) would always return true even if SPI is disabled because you're not actually reading the SPCR register... Or is this something weird that changed with arduino 1.0?? (although I think it's an avr-gcc constant and the Atmel AVR docs demonstrate its use as a bit-position constant so I can't imagine that would change across code versions)
--edit--
Yeah SPE is a #define'd constant, see (using MacOS X snow leopard here):
cd /Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/avr/include/avr
grep -E 'define.*SPE' *
io2333.h:#define SPE 6
io43u32x.h:#define SPE 6
io43u35x.h:#define SPE 6
io4414.h:#define SPE 6
io4433.h:#define SPE 6
io4434.h:#define SPE 6
...many more hits after this...

line 232 changed to for (i=_addrwidth; i>=0; i--)
About decreasing _addrwidth by 1, and the wrong address is choosen with a _addrwidth by 1 the loop never entered.

Not sure what you mean here... if _addrwidth=1 due to us having a 256-byte or 512-byte chip, then the loop runs once (i=0; i>=0; i--) which is the intended effect... notice the conditional is "i>=0" not "i>0"

Also please be aware, there was a bug/typo in the code someone brought up to me on the bitbucket, _addrwidth got mistakenly force-set to 1 (instead of being compared to the number 1) in an if statement at line 48. I've fixed this and committed the update. That might've been the source of your confusion/buggy behavior?

First SPIEEP.h
line 33 changed to
include <Arduino.h>
About the Arduino team changed the filename

to keep it portable one might use

#if ARDUINO < 100
#include <WProgram.h>
#else
#include <Arduino.h>
#endif

good call, thx... committing change :slight_smile:

Just a quick note for anyone who might be reading this in the future, the pins on the Mega 2560 are:

http://arduino.cc/en/Main/arduinoBoardMega2560

SPI: 50 (MISO), 51 (MOSI), 52 (SCK), 53 (SS). These pins support SPI communication using the SPI library. The SPI pins are also broken out on the ICSP header, which is physically compatible with the Uno, Duemilanove and Diecimila.

SS pin (Slave Select) is the so called CS pin (Chip Select) in the library and needs to be changed accordingly on

#define EEPROM_CSPIN 53  // Chip Select attached to pin 10 (53 on the Mega)

in order for it work.

Plus I can confirm that the library is working with the 25AA1024. Thank you very much for your effort!

Bug in the Zip file linked in original post (but the source in Bitbucket is ok)

File: SPIEEP.cpp

if (_addrwidth = 1 && totalsize == 512) // Is it a 24(AA|LC)040 512-byte chip?

should of course be

if (_addrwidth == 1 && totalsize == 512) // Is it a 24(AA|LC)040 512-byte chip?

Good lib - thanks for posting it.

Spirilis:

Have you moved the documentation for SPIEPP to a new repository?

The location on the arduino forum is dead.

Thanks