added my own little EEPROM library

the library provided, as far as i can tell, does not allow for *only*
erasing or *only* writing bytes, only for doing both at the same time.
partial-rewrite
Ben Blazak 2013-06-10 23:38:09 -07:00
parent d280078435
commit be8c826e90
3 changed files with 182 additions and 0 deletions

78
firmware/lib/eeprom.h Normal file
View File

@ -0,0 +1,78 @@
/* ----------------------------------------------------------------------------
* Copyright (c) 2013 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (see "doc/licenses/MIT.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
/** description
* EEPROM interface
*
* Prefix: `eeprom__`
*
* Notes: TODO
*/
#ifndef ERGODOX_FIRMWARE__LIB__EEPROM__H
#define ERGODOX_FIRMWARE__LIB__EEPROM__H
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
#include <stdint.h>
// ----------------------------------------------------------------------------
uint8_t eeprom__read (uint8_t * address);
void eeprom__write (uint8_t * address, uint8_t data);
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
#endif // ERGODOX_FIRMWARE__LIB__EEPROM__H
// ============================================================================
// === documentation ==========================================================
// ============================================================================
// === eeprom__read() ===
/** functions/eeprom__read/description
* Read and return the data at `address` in the EEPROM memory space
*
* Arguments:
* - `address: The address of (i.e. a pointer to) the location to operate on
*/
// === eeprom__write() ===
/** functions/eeprom__write/description
* Write `data` to `address` in the EEPROM memory space
*
* Arguments:
* - `address: The address of (i.e. a pointer to) the location to operate on
* - `data`: The data to write
*
*
* Notes:
*
* - Due to the technology used, EEPROM bytes, when cleared, have a logical
* value of `1`. Interesting stuff, but I didn't read about it thoroughly
* enough to give my own explanation here.
*
*
* Implementation notes:
*
* - If possible, this function should only modify when necessary; that is,
* when the data to be written is different than the data that's already
* there. This requires more processor time (to read the current value and
* compare), but it's better for the EEPROM (which has a limited write life),
* and will allow the operation to complete *much* more quickly in the event
* that the data has not changed.
*
* - If possible, writing `0xFF` should clear the memory (without writing
* anything), and writing to a location currently set to `0xFF` should write
* without clearing first.
*/

View File

@ -0,0 +1,89 @@
/* ----------------------------------------------------------------------------
* Copyright (c) 2013 Ben Blazak <benblazak.dev@gmail.com>
* Released under The MIT License (see "doc/licenses/MIT.md")
* Project located at <https://github.com/benblazak/ergodox-firmware>
* ------------------------------------------------------------------------- */
/** description
* Implements the EEPROM interface defined in "../eeprom.h" for the ATMega32U4
*
* This is meant to be a replacement for the read, write, and update functions
* provided by `<avr/eeprom.h>`, and should be preferred for those operations.
* There are other things provided by that header that may be useful however,
* and it's likely that both will be needed.
*
* These functions (and most of the comments) are taken more or less straight
* from the data sheet, section 5.3
*
* Assumptions
* - Voltage will never fall below the specified minimum for the clock
* frequency being used.
* - The address passed as `address` to any of the functions is valid.
* - A write to flash memory (PROGMEM) will never be in progress when any of
* these functions are called.
*/
#include <stdint.h>
#include <util/atomic.h>
#include <avr/io.h>
#include "../eeprom.h"
// ----------------------------------------------------------------------------
/** functions/eeprom__read/description
* Implementation notes:
*
* - If a write is in progress when this function is called, this function will
* busy wait until the write has been completed.
*/
uint8_t eeprom__read(uint8_t * address) {
while (EECR & (1<<EEPE)); // wait for previous write to complete
EEAR = address; // set up address register
EECR |= (1<<EERE); // start EEPROM read (then halt, 4 clock cycles)
return EEDR; // return the value in the data register
}
/** functions/eeprom__write/description
* Implementation notes:
*
* - If another write is in progress when this function is called, this
* function will busy wait until the first write has been completed.
*
* - This function starts the write to the EEPROM, but returns long before it
* has been completed.
*/
void eeprom__write(uint8_t * address, uint8_t data) {
// - if a write is in progress, this will also wait until it's finished
uint8_t old_data = eeprom__read(address);
if (data == old_data) {
// do nothing
return;
} else if (data == 0xFF) {
// erase only (1.8 ms)
EECR &= ~(1<<EEPM1); // clear
EECR |= (1<<EEPM0); // set
} else if (old_data == 0xFF) {
// write only (1.8 ms)
EECR |= (1<<EEPM1); // set
EECR &= ~(1<<EEPM0); // clear
} else {
// erase and write in one (atomic) operation (3.4 ms)
EECR &= ~(1<<EEPM1); // clear
EECR &= ~(1<<EEPM0); // clear
}
EEAR = address; // set up address register
EEDR = data; // set up data register
// - interrupts must be disabled between these two operations, or else
// "EEPROM Master Programming Enable" may time out (since it's cleared by
// hardware 4 clock cycles after being written to `1` by software)
ATOMIC_BLOCK(ATOMIC_FORCEON) {
EECR |= (1<<EEMPE); // set "EEPROM Master Programming Enable" to `1`
EECR |= (1<<EEPE); // start EEPROM write (then halt, 2 clock cycles)
}
}

View File

@ -0,0 +1,15 @@
# -----------------------------------------------------------------------------
# Copyright (c) 2013 Ben Blazak <benblazak.dev@gmail.com>
# Released under The MIT License (see "doc/licenses/MIT.md")
# Project located at <https://github.com/benblazak/ergodox-firmware>
# -----------------------------------------------------------------------------
## description
# eeprom options
#
# This file is meant to be included by the using '.../options.mk'
#
SRC += $(wildcard $(CURDIR)/$(MCU).c)