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
parent
d280078435
commit
be8c826e90
|
@ -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.
|
||||
*/
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
Loading…
Reference in New Issue