unified_retro_keyboard/firmware/asdf/eeprom-spec.org

3.6 KiB

EEPROM management

Uses

Store current keyboard ID

Store status of various options

key repeat rates and delays
communications delays
serial baud rates
keyboard macros
keyboard specific options
all caps / upper+lower
handling of special keys

Allocate on demand

System block does not change as keyboards are changed

Items include:

current keyboard

All system block allocation must occur before any keyboard allocation may occur.

Once system EEPROM is allocated, system EEPROM is "locked"

If system EEPROM is locked, then EEPROM cannot be reallocated, although the parameters may be re-written.

provision to unlock EEPROM, for example, when firmware is updated, or during development

Keyboard block is reset whenever the keyboard changes

Any parameters specific to a keyboard, such as macros, keymap-specific settings, etc. are stored here.

This section is erased when keymap changes, but not when a keymap is loaded from EEPROM at powerup.

Architecture

Device independent layer - allows diferent devices including on-chip EEPROM, off-chip EEPROM, and other technologies such as FRAM. An API that implements the following:

Read a byte/word from EEPROM

Write a byte/word to EEPROM

Erase a range of EEPROM

Return size of storage (in bytes)

Allocation layer

Store an arbitrary length string to a numbers slot (0-ff)

retrieve an arbitrary length string from a numbered slot (0-ff)

delete a string an a numbered slot (0-ff). Probably accomplish by storing a 0-length string.

Initialize an arbitary portion of storage (including all storage)

Architecture for allocation layer:

Pointer to first "free" block. This is a linked list of blocks.

Table of starting positions and lengths. Starting position will be 2 bytes, and will indicate a 1 or 2 byte boundary1, 2, or 4-byte words, determined by storage size. Number of elements in table will also be determined by storage size, up to max 255.

Initialize with a free block of all available storage

Allocate storage from beginning of free block.

The beginning of each block is a header including a "size" value (1 or 2 bytes) and a "link" address, 1, 2, or 4 bytes, same as the index table. For free blocks, the "size" is always a contiguous size. For allocated blocks, the size is the total size of all the blocks linked in a list.

To allocate:

Look up the first free block
If the string can fit in the size of the free block:
then store size in the size field
store "0" in the link
store the string next.
If there is any space left over in the free block, then create a new "free block" from the next few bytes, and add to the front of the "free" list.
If the string cannot fit in the size of the free block:
store the size in the size field
Leave the "link" address, which points to the next free block
Store the string text
jump to the next free block, and repeat the above for the remainder of the string.
keep repeating until the string can fit in a free block.
If there is no more free block, and not enough room to store the text, then store as much as possible, then stop.

To free:

Look up the string address in the index
Zero out the index entry for the string.
Look at the size of the string. If the next contiguous block is also free, then combine and store the size of the combined block at the beginning of the block.
repeat the above until next contiguous block is not free
Please free block at the beginning of the "free" list.