day09/ex04/include/lib/eeprom.h
2026-04-27 15:29:51 +02:00

70 lines
1.6 KiB
C

#ifndef EEPROM_H
#define EEPROM_H
#include <avr/io.h>
#include "lib/interupt.h"
#include "lib/mystd.h"
static inline void eeprom_wait(void) {
while (EECR & BV(EEPE))
;
}
static inline void eeprom_write_single_nocheck(uint16_t addr, uint8_t data) {
uint8_t sreg_save = SREG;
my_cli();
// wait until eeprom is good to go !
eeprom_wait();
while (SPMCSR & BV(SPMEN))
;
// setup the (addr, data) pair
EEAR = addr;
EEDR = data;
// we set the EEPROM master write bit
EECR = (EECR & ~BV(EEPE)) | BV(EEMPE);
// within four cpu cycle, we need to set the EEPROM write bit, otherwise the writes doesnt work
// why 4 ? -> the master bit is reset after 4 cycles, and you need both to actually write
EECR |= BV(EEPE);
// this is the exact setup written in p32
// here the write should be done
SREG = sreg_save;
}
static inline uint8_t eeprom_read_single(uint16_t addr) {
uint8_t sreg_save = SREG;
my_cli();
eeprom_wait();
EEAR = addr;
EECR |= BV(EERE);
SREG = sreg_save;
return EEDR;
}
// true on error
static inline bool eeprom_write_single(uint16_t addr, uint8_t data) {
if (eeprom_read_single(addr) != data)
eeprom_write_single_nocheck(addr, data);
return (eeprom_read_single(addr) != data);
}
// true on error
static inline bool eeprom_write(uint16_t addr, const uint8_t* data, uint16_t length) {
for (uint16_t i = 0; i < length; i++) {
if (eeprom_write_single(addr + i, data[i]))
return true;
}
return false;
}
static inline void eeprom_read(uint16_t addr, uint8_t* data, uint16_t length) {
for (uint16_t i = 0; i < length; i++)
data[i] = eeprom_read_single(addr + i);
}
#endif /* EEPROM_H */