# SFBEeprom.h File Reference

Reading and writing the SFB onboard EEPROM. More...

`#include "SFBTypes.h"`

Include dependency graph for SFBEeprom.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

## Defines
#define | EEPROM_SIZE_BYTES (1<<14)
| Total raw EEPROM size.
#define | EEPROM_BYTES_PER_PAGE 64
| Bytes per page in the EEPROM.
#define | EEPROM_RESERVED_PAGES 2
| Pages reserved at end of EEPROM for SFB bootblock.
#define | EEPROM_RESERVED_BYTES (EEPROM_RESERVED_PAGES*EEPROM_BYTES_PER_PAGE)
| Bytes reserved at end of EEPROM for SFB bootblock.
## Functions
void | eepromWrite (u32 addr, const u8 *source, u32 length)
| Write data from memory to the EEPROM data partition.
void | eepromRead (u32 addr, u8 *dest, u32 length)
| Read data from the EEPROM data partition into RAM.
void | eepromWait (bool busyWait=false)
| Wait for any in-progress EEPROM write to complete.
u32 | eepromSize ()
| Get the EEPROM data partition size.
void | eepromWriteReserved (const u32 addr, const u8 *data, const u32 length)
| Write data from memory to the EEPROM SFB reserved partition.
void | eepromReadReserved (const u32 addr, u8 *data, const u32 length)
| Read data from the EEPROM SFB reserved partition into RAM.
void | eeprom_startup_initialization ()
| Initialize the EEPROM subsystem.

## Detailed Description

Reading and writing the SFB onboard EEPROM.

The SFB contains a 16KB EEPROM for storing "persistent" data. An EEPROM (Electrically-Eraseable Programmable Read-Only Memory) is a device that retains data for long periods, even when powered off, while also allowing the stored data to be altered and updated under program control, without any additional hardware.

Out of the 16,384 bytes in the SFB EEPROM, the last 128 (EEPROM_RESERVED_BYTES) bytes are reserved for SFB library use, while the first 99.2% of the EEPROM is available for sketch use.

Those final 128 EEPROM bytes are called the "SFB bootblock" or the "EEPROM reserved partition", while the initial 16,256 bytes are called the "EEPROM data partition". Within the EEPROM data partition, there is no predefined structure or "file system", there are just persistent bytes, located at EEPROM addresses from 0 through 16255, available to be read and written however the sketch wishes.

Hardware and implementation details:

- The EEPROM is arranged in "pages" each of which is 64 (EEPROM_BYTES_PER_PAGE) bytes long.

- In general, reading from the EEPROM is a relatively fast operation, taking a small number of microseconds per byte read, but there is also "command overhead" time, so fewer, larger reads will perform better than more, smaller ones:

          const int N = 1000;
          char buf[N];
          for (u32 i = 0; i < N; ++i) eepromRead(i, &buf[i], 1);  // Read first N bytes of EEPROM (slowly)
          eepromRead(0,buf,N);                                    // Has the same result, but much faster

- Compared to EEPROM reading, writing to the EEPROM is slow, on the order of perhaps 5 milliseconds. That time is required for each page of EEPROM written to, regardless of how many bytes per page are affected:

          const int N = 50;
          char buf[N] = ..some data..
          eepromWrite(100,buf,N);   // Write 50 bytes to addrs 100..149 -- hits two pages, so TWO write cycles
          eepromWrite(128,buf,N);   // Write 50 bytes to addrs 128..177 -- hits one page, so ONE write cycle

- Note, however, that eepromWrite() returns as soon as the (final) write cycle has started, without waiting for it to complete, so if a single eepromWrite() call is made that affects only a single page of EEPROM, it will return relatively quickly. However, the write cycle must still complete before other EEPROM operations can commence:

          char buf[3];

          u32 start = micros();               // Get start time, then
          eepromWrite(0,"foo",3);             // Write 3 bytes into one page

          u32 split = micros();               // Get split time
          eepromRead(64,buf,3);               // Read 3 bytes from one page

          u32 end = micros();                 // Get end time

          pprintf("Write=%d, read=%d\n", split-start, end-split); // Shows read slower than write!

because the eepromRead() has to wait for the write cycle started by the eepromWrite() to complete. By comparison:

          char buf[3];

          u32 start = micros();               // Get start time, then
          eepromWrite(0,"foo",3);             // Write 3 bytes into one page
          eepromWait();                       // Wait for write cycle to complete

          u32 split = micros();               // Get split time
          eepromRead(64,buf,3);               // Read 3 bytes from one page

          u32 end = micros();                 // Get end time

          pprintf("Write=%d, read=%d\n", split-start, end-split); // Now read much faster than write!

Author:
  David H. Ackley.

Date:
  (C) 2009 All rights reserved.

Code License:
  The GNU Lesser General Public License

License Note:
  All code samples shown in documentation are placed into the public domain.

## Function Documentation

void eeprom_startup_initialization | ( |  | ) |

Initialize the EEPROM subsystem.

Intended for library internal use only. Called automatically during SFB system startup.

Side Effects:
  The EEPROM subsystem is initialized.

void eepromRead | ( | u32 | addr,
|  | u8 * | dest,
|  | u32 | length |
| ) |  |  |

Read data from the EEPROM data partition into RAM.

Wait for any in-progress EEPROM write to complete, if necessary, then read length bytes from EEPROM data partition locations starting at addr (`addr`..addr+length-1) into RAM addresses starting at dest (`dest`[0]..dest[length-1]).

Parameters:

  | addr | EEPROM data partition address to begin reading from.
  | dest | RAM address to begin writing to.
  | length | Number of bytes to read.

Blinks:
  E_API_NULL_POINTER if dest is null.

Blinks:
  E_API_EEPROM_ADDRESS if addr + length is not less than eepromSize()

Side Effects:
  RAM is written if length is non-zero.

Examples:
  eeprom1.cpp, eeprom2.cpp, eeprom3.cpp, and eeprom4.cpp.

void eepromReadReserved | ( | const u32 | addr,
|  | u8 * | data,
|  | const u32 | length |
| ) |  |  |

Read data from the EEPROM SFB reserved partition into RAM.

Intended for library internal use. Wait for any in-progress EEPROM write to complete, if necessary, then read length bytes from EEPROM SFB reserved partition locations starting at addr (`addr`..addr+length-1) into RAM addresses starting at data (`data`[0]..data[length-1]).

Parameters:

  | addr | EEPROM data partition address to begin reading from.
  | data | RAM address to begin writing to.
  | length | Number of bytes to read.

Blinks:
  E_API_NULL_POINTER if dest is null.

Blinks:
  E_API_EEPROM_ADDRESS if addr + length is not less than eepromSize()

Side Effects:
  RAM is written if length is non-zero.

u32 eepromSize | ( |  | ) |

Get the EEPROM data partition size.

Returns:
  The size of the EEPROM data partition

void eepromWait | ( | bool | busyWait = `false` | ) |

Wait for any in-progress EEPROM write to complete.

Normally doesn't need to be called explicitly, since the other EEPROM routines wait as needed.

Parameters:

  | busyWait | Specify how to wait. If bustWait is `false` or omitted, use delay(u32) function to perform the waiting, otherwise use delayMicroseconds(u32).

Blinks:
  E_API_EEPROM_RESPONSE if the EEPROM fails to respond in a timely manner (i.e., four times its datasheet-specified maximum latency).

Examples:
  eeprom3.cpp.

void eepromWrite | ( | u32 | addr,
|  | const u8 * | source,
|  | u32 | length |
| ) |  |  |

Write data from memory to the EEPROM data partition.

Writes length bytes from source (`source`[0]..source[length-1]) to EEPROM locations starting at addr (`addr`..addr+length-1).

Parameters:

  | addr | EEPROM data partition address to begin writing to.
  | source | Memory address to begin reading from.
  | length | Number of bytes to write.

Blinks:
  E_API_NULL_POINTER if source is null.

Blinks:
  E_API_EEPROM_ADDRESS if addr+length is not less than eepromSize()

Attention:
  WARNING! This routine returns before the EEPROM write cycle has completed. If that is a problem -- e.g. because the board is about to power down -- then eepromWait() should be called after eepromWrite().

Side Effects:
  EEPROM memory is written if length is non-zero.

Examples:
  eeprom1.cpp, eeprom2.cpp, eeprom3.cpp, and eeprom4.cpp.

void eepromWriteReserved | ( | const u32 | addr,
|  | const u8 * | data,
|  | const u32 | length |
| ) |  |  |

Write data from memory to the EEPROM SFB reserved partition.

Intended for library internal use only! Improper use can corrupt an SFB's bootblock.

Writes length bytes from data (`data`[0]..data[length-1]) to EEPROM reserved locations starting at addr (`addr`..addr+length-1).

Parameters:

  | addr | EEPROM reserved partition address to begin writing to.
  | data | Memory address to begin reading from.
  | length | Number of bytes to write.

Blinks:
  E_API_NULL_POINTER if data is null.

Blinks:
  E_API_EEPROM_ADDRESS if addr + length is greater than EEPROM_RESERVED_BYTES

Attention:
  WARNING! This routine returns before the EEPROM write cycle has completed. If that is a problem -- e.g. because the board is about to power down -- then eepromWait() should be called after eepromWriteReserved() returns.

Side Effects:
  EERPROM memory is written if length is non-zero.