#ifndef EEPROM_H_
#define EEPROM_H_

#include <stdint.h>
#include <spi.h>
#include <config.h>
#include <assert.h>



#define EEPROM_WRITE_BLOCK_SIZE 32
#define EEPROM_AFTER_WRITE_DELAY 7


typedef struct __attribute__((__packed__)) s_eepromHeader {
  uint32_t magic;
  uint32_t writeCounter;
} t_eepromHeader;
static_assert((sizeof(t_eepromHeader) <= EEPROM_WRITE_BLOCK_SIZE), "t_eepromHeader has illegal size, must be less than or equal 32");

typedef struct __attribute__((__packed__)) s_deviceStats {
    uint32_t totalRunningHours;
    uint32_t totalPowercycles;
    uint32_t totalRequests;
    uint32_t totalFailures;
} t_deviceStats;
static_assert((sizeof(t_deviceStats) <= EEPROM_WRITE_BLOCK_SIZE), "t_deviceStats has illegal size, must be less than or equal 32");

static_assert((sizeof(t_configBlock) % 32 == 0), "t_configBlock has illegal size, must be dividable by 32");
static_assert((sizeof(t_deviceBlock) % 32 == 0), "t_deviceBlock has illegal size, must be dividable by 32");


#define EEPROM_BASE_ADDR 0
#define EEPROM_DEVICE_STATS_ADDR 32
#define EEPROM_CONFIG_BLOCK_ADDR 64
#define EEPROM_DEVICE_BLOCK_BASE_ADDR (EEPROM_CONFIG_BLOCK_ADDR + sizeof(t_configBlock))



void eepromInit();
void eepromWrite(uint16_t addr, uint8_t *buf, uint8_t len);
void eepromRead(uint16_t addr, uint8_t *buf, uint8_t len);
void eepromSpiTxCpltCallback(SPI_HandleTypeDef *hspi);
t_deviceStats* getGlobalDeviceStats();
void eepromReadConfigBlock(t_configBlock *destConfigBlock);
void eepromWriteConfigBlock(t_configBlock *srcConfigBlock);
void eepromReadDeviceBlock(uint8_t blockNum, t_deviceBlock *destDeviceBlock);
void eepromWriteDeviceBlock(uint8_t blockNum, t_deviceBlock *srcDeviceBlock);

#endif /* EEPROM_H_ */
