#include "eeprom.h"
#include "stdio.h"
#include "string.h"
/********************************************************/

// Eeprom state related defines

/*****************EEPROM_EMULATOR************************/

typedef struct
{
  // Schnittstellenparameter
  uint32_t     baudrate;            
  uint16_t     parityMode;                                  
  uint16_t     stopBits;       
  uint16_t     slaveAddress;

  // Cell Parameter
  uint16_t    ovpAlarm; 
  uint16_t    lvpAlarm; 
  uint16_t    ovpStart;
  uint16_t    ovpStop;
  uint16_t    lvpStart;
  uint16_t    lvpStop;
  uint16_t    vShutdownStart;
  uint16_t    vShutdownStop; 
  int16_t     otShutdownStart;
  int16_t     otShutdownStop;
  int16_t     utpChargeStart;
  int16_t     utpChargeStop;       
  int16_t     utpDischargeStart;
  int16_t     utpDischargeStop;
  uint16_t    lvpTime;
  uint16_t    defaultBalVoltage;
  
  // tempco
  int16_t     refTemp;
  int16_t     ovpAlarmTempco;
  int16_t     lvpAlarmTempco;
  int16_t     ovpStartTempco;
  int16_t     ovpStopTempco;
  int16_t     lvpStartTempco;
  int16_t     lvpStopTempco;     
  int16_t     vShutdownStartTempco;
  int16_t     vShutdownStopTempco; 
  int16_t     balancerVoltageTempco;
  uint16_t    lockKey;
}eeprom_data_t;

typedef struct 
{
  // Geräteinformation
  uint32_t    SN;
  uint8_t     deviceInfoWritten;
  uint8_t     resv[3];
}device_info_t;


typedef struct
{
  // Eeprom Status Infos
  uint32_t     writeCounter;
  uint16_t     structureSize;
  uint16_t     revisionInfo;
   uint8_t     firstStartId;
}eeprom_state_t;


typedef struct
{
  // Eeprom Status Infos
  uint16_t    cycleCounter;
  uint16_t    minVoltage;
  uint16_t    maxVoltage;
  int16_t     minTemperature;
  int16_t     maxTemperature;
  uint16_t    criticalOverTempTime;
  uint16_t    criticalUnderTempTime;
  uint16_t    criticalOvervoltageTime;
  uint16_t    criticalUndervoltageTime;

}log_data_t;

// fasse zu einer Struktur zusammen um nachher einfach darauf zugreifen zu können
typedef struct
{
  eeprom_data_t changedData;
  eeprom_state_t  eepromState;
  device_info_t deviceInfo;
  log_data_t logData;
}eeprom_stored_data_t;

// Flash related defines
#define USER_FLASH_BASE_ADRESS                    FLASH_BASE

#define USER_FLASH_SIZE                           FLASH_SIZE
//#define USER_FLASH_END                            ((USER_FLASH_BASE_ADRESS + USER_FLASH_SIZE) - 1)
#define USER_FLASH_END                            (USER_FLASH_BASE_ADRESS + USER_FLASH_SIZE)
#define USER_FLASH_PAGE_SIZE                      (0x800)

// Eeprom emulator related defines
#define NUMBER_OF_PAGES                           (2)
#define USER_EEPROM_BASE_ADRESS                   (USER_FLASH_END - (USER_FLASH_PAGE_SIZE * NUMBER_OF_PAGES))

// Data to store reated defines
#define SIZEOF_DEFAULT_EEPROM_DATA                (sizeof(eeprom_data_t))
#define SIZEOF_CHANGED_EEPROM_DATA                (sizeof(eeprom_data_t))
#define SIZEOF_DEVICE_INFO                        (sizeof(device_info_t))
#define SIZEOF_EEPROM_STATE                       (sizeof(eeprom_state_t))

#define SIZE_OF_DATA_TO_STORE                     (SIZEOF_CHANGED_EEPROM_DATA + SIZEOF_DEVICE_INFO + SIZEOF_EEPROM_STATE)

// Adress related defines
#define EEPROM_ADRESS_FIRST_START_ID              (USER_EEPROM_BASE_ADRESS - 1 + SIZE_OF_DATA_TO_STORE - 1 - SIZEOF_DEVICE_INFO - 1 - 1)
#define FIRST_START_ID                            (1)


static uint32_t GetPage(uint32_t Address);
static HAL_StatusTypeDef getEEPROMData(uint32_t address, uint8_t * data, uint32_t len);

// muss modulo 8 noch hinzufügen wg 8 byte alignement
static uint64_t eepromData[(SIZE_OF_DATA_TO_STORE / 8) + 1];
static uint64_t eepromLogData[(sizeof(log_data_t) / 8) + 1];
static FLASH_EraseInitTypeDef EraseInitStruct = {0};

extern uint16_t savedLockKey;

static const eeprom_data_t defaultEepromData =
{
  // Schnittstellenparameter
  MB_BAUDRATE_DEFAULT,   
  MB_PARITY_MODE_DEFAULT,
  MB_STOPBIT_MODE_DEFAULT,        /*uint16_t     stopbitmode, reserviert;*/                           
  MB_SLAVE_ADDRESS_DEFAULT,        /*uint16_t     slave_adress;*/  
  OVP_ALARM_VOLTAGE_DEFAULT,
  LVP_ALARM_VOLTAGE_DEFAULT,
  OVP_START_VOLTAGE_DEFAULT,
  OVP_STOPP_VOLTAGE_DEFAULT,
  LVP_START_VOLTAGE_DEFAULT,
  LVP_STOPP_VOLTAGE_DEFAULT,
  VOLTAGE_SHUTDOWN_START_VOLTAGE_DEFAULT,
  VOLTAGE_SHUTDOWN_STOPP_VOLTAGE_DEFAULT,
  OVERTEMPPROTECTION_START_DEFAULT,
  OVERTEMPPROTECTION_STOP_DEFAULT,
  UNDERTEMPPROTECTION_CHARGE_START_DEFAULT,
  UNDERTEMPPROTECTION_CHARGE_STOP_DEFAULT,
  UNDERTEMPPROTECTION_DISCHARGE_START_DEFAULT,
  UNDERTEMPPROTECTION_DISCHARGE_STOP_DEFAULT,
  LVP_TIME_DEFAULT,
  BAL_VOLTAGE_DEFAULT,
  BASIS_TEMP_DEFAULT,
  OVP_ALARM_TEMPCO_DEFAULT,
  LVP_ALARM_TEMPCO_DEFAULT,
  OVP_START_TEMPCO_DEFAULT,
  OVP_STOPP_TEMPCO_DEFAULT,
  LVP_START_TEMPCO_DEFAULT,
  LVP_STOPP_TEMPCO_DEFAULT,
  V_SHUTDOWN_START_TEMPCO_DEFAULT,
  V_SHUTDOWN_STOPP_TEMPCO_DEFAULT,
  BAL_TEMPCO_DEFAULT,
  0,                                  //Lockkey, Default keiner!
};

/**
  * @brief  Gets the page of a given address
  * @param  Addr: Address of the FLASH Memory
  * @retval The page of a given address
  */
static uint32_t GetPage(uint32_t Addr)
{
  return (Addr - FLASH_BASE) / FLASH_PAGE_SIZE;
}

static HAL_StatusTypeDef getEEPROMData(uint32_t address, uint8_t * data, uint32_t len)
{
    uint32_t i = 0;
    uint8_t daten;
    if((address + len) > USER_FLASH_END)
    {
      return HAL_ERROR;
    }
    for(i = 0; i < len; i ++)
    {
      data[i] = *((uint8_t *) (address + i));
    }
    return HAL_OK;
}

bool EEPROM_isFirstStart()
{

  uint8_t firstStartCatcher;
  if(getEEPROMData(EEPROM_ADRESS_FIRST_START_ID, (uint8_t *)&firstStartCatcher, 1) != HAL_OK) return HAL_ERROR;
  if(firstStartCatcher != FIRST_START_ID)
  {
    printf ("First start detected\n");
    return true;

  }
  else
  {
    printf ("previous config present\n");
    return false;
  }
}

HAL_StatusTypeDef EEPROM_fullRestore(sys_data_t * data, bool keepSN)
{
  eeprom_stored_data_t * dataToStore;
  uint32_t PageError;
  uint32_t Address;
  uint32_t x;

  printf("EEPROM FULL RESTORE!\n");

  /****************LESE_DEFAULT_WERTE************************/

  dataToStore = (eeprom_stored_data_t *) eepromData;
  
  memcpy( (void *) &dataToStore->changedData, (void*) &defaultEepromData, sizeof(dataToStore->changedData)) ;
  
  
  // Eeprom Status Infos
  dataToStore->eepromState.writeCounter ++;
  dataToStore->eepromState.structureSize = sizeof(eeprom_stored_data_t);
  dataToStore->eepromState.revisionInfo = 0;
  dataToStore->eepromState.firstStartId = FIRST_START_ID;
  
  /****************PAGE_LÖSCHEN********************/   
  HAL_FLASH_Unlock();
   
  // check for PG bit set if so clear bit
  FLASH_WaitForLastOperation(1000);
  if(READ_BIT(FLASH->CR, FLASH_CR_PG)) 
  {
    CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
  }
 
  /* Fill EraseInit structure*/
  //Speicherung in vorletzter page, deshalb diese löschen.
  //Log Daten kommen in die letzte page
  EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
  EraseInitStruct.Page        = FLASH_PAGE_NB - 2; //GetPage(USER_EEPROM_BASE_ADRESS);
  EraseInitStruct.NbPages     = 1;

  /* erase Sektoren daten d+rfen nicht im instuction cache liegen  */
  if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
  {
    while (1)
    {
      // ERROR HAL_FLASH_GetError() kann info geben
    }
  }

  /****************IM_FLASH_SPEICHERN********************/

  /* programmiere uint64_t */
  Address = USER_EEPROM_BASE_ADRESS;
  x = 0;
  while (Address < (USER_EEPROM_BASE_ADRESS + SIZE_OF_DATA_TO_STORE))
  {
    if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, eepromData[x]) == HAL_OK)
    {
      Address = Address + 8;
      x ++;
    }
   else
    {
      /* Error occurred while writing data in Flash memory.
         User can add here some code to deal with this error */
      while (1)
      {
        // ERROR
      }
    }
  }

  /* Lock the Flash */
  HAL_FLASH_Lock();

  /****************AUSLESEN_UND_PRÜFEN********************/

  return EEPROM_readConfig(data);


}



HAL_StatusTypeDef EEPROM_storeConfig(sys_data_t * data,bool withSN, bool saveNewKey)
{
  eeprom_stored_data_t * dataToStore;
  uint32_t PageError;
  uint32_t Address;
  uint32_t x;
  /****************LESE_WERTE_AUS_SYSDATA*********************/ 
  printf("EEPROM STORE CONFIG!\n");
  dataToStore = (eeprom_stored_data_t *) eepromData;
  
  // Schnittstellenparameter
  dataToStore->changedData.baudrate = data->s.baudrate;            
  dataToStore->changedData.parityMode = data->s.parityMode;                                     
  dataToStore->changedData.stopBits = data->s.stopBits;
  dataToStore->changedData.slaveAddress = data->s.slaveAddress; 

    // Cell Parameter
  dataToStore->changedData.ovpAlarm = data->s.ovpAlarm;
  dataToStore->changedData.lvpAlarm = data->s.lvpAlarm;
  dataToStore->changedData.ovpStart = data->s.ovpStart;
  dataToStore->changedData.ovpStop  = data->s.ovpStop;
  dataToStore->changedData.lvpStart = data->s.lvpStart;
  dataToStore->changedData.lvpStop  = data->s.lvpStop;
  dataToStore->changedData.vShutdownStart  = data->s.vShutdownStart;
  dataToStore->changedData.vShutdownStop   = data->s.vShutdownStop;
  dataToStore->changedData.otShutdownStart = data->s.otShutdownStart;
  dataToStore->changedData.otShutdownStop  = data->s.otShutdownStop;
  dataToStore->changedData.utpChargeStart  = data->s.utpChargeStart;
  dataToStore->changedData.utpChargeStop   = data->s.utpChargeStop;
  dataToStore->changedData.utpDischargeStart = data->s.utpDischargeStart;
  dataToStore->changedData.utpDischargeStop  = data->s.utpDischargeStop;
  dataToStore->changedData.lvpTime           = data->s.lvpTime;
  dataToStore->changedData.defaultBalVoltage = data->s.defaultBalVoltage;

   // tempco
  dataToStore->changedData.refTemp = data->s.refTemp;
  dataToStore->changedData.ovpAlarmTempco = data->s.ovpAlarmTempco;
  dataToStore->changedData.lvpAlarmTempco = data->s.lvpAlarmTempco;
  dataToStore->changedData.ovpStartTempco = data->s.ovpStartTempco;
  dataToStore->changedData.ovpStopTempco  = data->s.ovpStopTempco;
  dataToStore->changedData.lvpStartTempco = data->s.lvpStartTempco;
  dataToStore->changedData.lvpStopTempco  = data->s.lvpStopTempco;
  dataToStore->changedData.vShutdownStartTempco = data->s.vShutdownStartTempco;
  dataToStore->changedData.vShutdownStopTempco = data->s.vShutdownStopTempco;
  dataToStore->changedData.balancerVoltageTempco = data->s.balancerVoltageTempco;

  if (saveNewKey)
  {
    dataToStore->changedData.lockKey = data->s.newLockKey;
  }
  else
  {
    dataToStore->changedData.lockKey = savedLockKey;
  }
  

  // Eeprom Status Infos
  dataToStore->eepromState.writeCounter ++ ;
  dataToStore->eepromState.structureSize = sizeof(eeprom_stored_data_t);
  dataToStore->eepromState.revisionInfo = 0;
  dataToStore->eepromState.firstStartId = FIRST_START_ID;

  if (withSN)
  {
    printf("Writing SN!\n");
    dataToStore->deviceInfo.SN = data->s.deviceSn;
  }

  /****************PAGE_LÖSCHEN********************/ 
  HAL_FLASH_Unlock();

  // check for PG bit set if so clear bit
  FLASH_WaitForLastOperation(1000);
  if(READ_BIT(FLASH->CR, FLASH_CR_PG)) 
  {
    CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
  }

  /* Fill EraseInit structure*/
  EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
  EraseInitStruct.Page        = FLASH_PAGE_NB - 2; 
  EraseInitStruct.NbPages     = 1;

  /* erase Sektoren daten dürfen nicht im instuction cache liegen  */
  if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
  {
    while (1)
    {
      // ERROR HAL_FLASH_GetError() kann info geben
    }
  }

  /****************IM_FLASH_SPEICHERN********************/

  /* programmiere uint64_t */
  Address = USER_EEPROM_BASE_ADRESS;
  x = 0;
  while (Address < (USER_EEPROM_BASE_ADRESS + SIZE_OF_DATA_TO_STORE))
  {
    if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, eepromData[x]) == HAL_OK)
    {
      Address = Address + 8;
      x ++;
    }
   else
    {
      /* Error occurred while writing data in Flash memory.
         User can add here some code to deal with this error */
      while (1)
      {
        // ERROR
      }
    }
  }

  /* Lock the Flash */
  HAL_FLASH_Lock();

  /****************AUSLESEN_UND_PRÜFEN********************/

  return EEPROM_readConfig(data);


}

HAL_StatusTypeDef EEPROM_storeLogData()
{
  
  uint32_t PageError;
  uint32_t Address;
  uint32_t x;
  log_data_t * logData;
  /****************LESE_WERTE_AUS_SYSDATA*********************/ 
  printf("EEPROM STORE LOG DATA!\n");

  //Zeiger auf Resevierten Ram Speicher, der für das speichern der Daten zuständig ist
  logData = (log_data_t *) eepromLogData;
  logData->cycleCounter = sysData.s.cycleCounter;
  logData->maxVoltage = sysData.s.maxVoltage;
  logData->minVoltage = sysData.s.minVoltage;
  logData->maxTemperature = sysData.s.maxTemperature;
  logData->minTemperature = sysData.s.minTemperature;
  logData->criticalOvervoltageTime = sysData.s.criticalOverVoltageTime;
  logData->criticalUndervoltageTime = sysData.s.criticalUnderVoltageTime;
  logData->criticalOverTempTime = sysData.s.criticalOverTempTime;
  logData->criticalUnderTempTime = sysData.s.criticalUnderTempTime;
  

  /****************PAGE_LÖSCHEN********************/ 
  HAL_FLASH_Unlock();

  // check for PG bit set if so clear bit
  FLASH_WaitForLastOperation(1000);
  if(READ_BIT(FLASH->CR, FLASH_CR_PG)) 
  {
    CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
  }

  /* Fill EraseInit structure*/
  EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
  EraseInitStruct.Page        = FLASH_PAGE_NB - 1;  // Page löschen 
  EraseInitStruct.NbPages     = 1;

  /* erase Sektoren daten dürfen nicht im instuction cache liegen  */
  if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
  {
    printf("Error while deleting log data area in flash\n");
    return HAL_ERROR;
  }

  /****************IM_FLASH_SPEICHERN********************/

  /* programmiere uint64_t */
  uint32_t startAdress =  USER_EEPROM_BASE_ADRESS + FLASH_PAGE_SIZE;
  Address = startAdress;
  x = 0;
  while (Address < (startAdress + sizeof(log_data_t)))
  {
    if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, eepromLogData[x]) == HAL_OK)
    {
      Address = Address + 8;
      x ++;
    }
   else
    {
        printf("Error while saving data to flash\n");
        return HAL_ERROR;
    }
  }

  /* Lock the Flash */
  HAL_FLASH_Lock();

  return HAL_OK;
}


HAL_StatusTypeDef EEPROM_ResetLogData()
{
  
  uint32_t PageError;
  uint32_t Address;
  uint32_t x;
  log_data_t * logData;
  /****************LESE_WERTE_AUS_SYSDATA*********************/ 
  printf("EEPROM STORE LOG DATA!\n");

  //Zeiger auf Resevierten Ram Speicher, der für das speichern der Daten zuständig ist
  logData = (log_data_t *) eepromLogData;
  logData->cycleCounter = 0;
  logData->maxVoltage = 0;
  logData->minVoltage = UINT16_MAX;
  logData->maxTemperature = INT16_MIN;
  logData->minTemperature = INT16_MAX;
  logData->criticalOvervoltageTime = 0;
  logData->criticalUndervoltageTime = 0;
  logData->criticalOverTempTime = 0;
  logData->criticalUnderTempTime = 0;
  

  /****************PAGE_LÖSCHEN********************/ 
  HAL_FLASH_Unlock();

  // check for PG bit set if so clear bit
  FLASH_WaitForLastOperation(1000);
  if(READ_BIT(FLASH->CR, FLASH_CR_PG)) 
  {
    CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
  }

  /* Fill EraseInit structure*/
  EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
  EraseInitStruct.Page        = FLASH_PAGE_NB - 1;  // Page löschen 
  EraseInitStruct.NbPages     = 1;

  /* erase Sektoren daten dürfen nicht im instuction cache liegen  */
  if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
  {
    printf("Error while deleting log data area in flash\n");
    return HAL_ERROR;
  }

  /****************IM_FLASH_SPEICHERN********************/

  /* programmiere uint64_t */
  uint32_t startAdress =  USER_EEPROM_BASE_ADRESS + FLASH_PAGE_SIZE;
  Address = startAdress;
  x = 0;
  while (Address < (startAdress + sizeof(log_data_t)))
  {
    if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, eepromLogData[x]) == HAL_OK)
    {
      Address = Address + 8;
      x ++;
    }
   else
    {
        printf("Error while saving data to flash\n");
        return HAL_ERROR;
    }
  }

  /* Lock the Flash */
  HAL_FLASH_Lock();

  return HAL_OK;
}



HAL_StatusTypeDef EEPROM_readConfig(sys_data_t * data)
{
  eeprom_stored_data_t * dataToStore;

  /****************WERTE_AUS_FLASH_LESEN********************/
  
  
  if(getEEPROMData(USER_EEPROM_BASE_ADRESS, (uint8_t *)eepromData, sizeof(eepromData)) != HAL_OK) return HAL_ERROR;

  dataToStore = (eeprom_stored_data_t *) eepromData;
  
  // Schnittstellenparameter
  data->s.baudrate = dataToStore->changedData.baudrate;            
  data->s.parityMode = dataToStore->changedData.parityMode;      
  data->s.stopBits = dataToStore->changedData.stopBits;      
  data->s.slaveAddress = dataToStore->changedData.slaveAddress; 

  //   // Cell Parameter
  data->s.ovpAlarm = dataToStore ->changedData.ovpAlarm;
  data->s.lvpAlarm = dataToStore ->changedData.lvpAlarm;
  data->s.ovpStart = dataToStore ->changedData.ovpStart;
  data->s.ovpStop  = dataToStore ->changedData.ovpStop;
  data->s.lvpStart = dataToStore ->changedData.lvpStart;
  data->s.lvpStop  = dataToStore ->changedData.lvpStop;
  data->s.vShutdownStart    = dataToStore->changedData.vShutdownStart;
  data->s.vShutdownStop     = dataToStore->changedData.vShutdownStop;
  data->s.otShutdownStart   = dataToStore->changedData.otShutdownStart;
  data->s.otShutdownStop    = dataToStore->changedData.otShutdownStop;
  data->s.utpChargeStart    = dataToStore->changedData.utpChargeStart;
  data->s.utpChargeStop     = dataToStore->changedData.utpChargeStop;
  data->s.utpDischargeStart = dataToStore->changedData.utpDischargeStart;
  data->s.utpDischargeStop  = dataToStore->changedData.utpDischargeStop; 
  data->s.lvpTime           = dataToStore->changedData.lvpTime;
  data->s.defaultBalVoltage = dataToStore->changedData.defaultBalVoltage;


  // tempco
  data->s.refTemp = dataToStore ->changedData.refTemp;
  data->s.ovpAlarmTempco = dataToStore ->changedData.ovpAlarmTempco;
  data->s.lvpAlarmTempco =  dataToStore ->changedData.lvpAlarmTempco;
  data->s.ovpStartTempco = dataToStore ->changedData.ovpStartTempco;
  data->s.ovpStopTempco = dataToStore->changedData.ovpStopTempco;
  data->s.lvpStartTempco = dataToStore->changedData.lvpStartTempco;
  data->s.lvpStopTempco = dataToStore->changedData.lvpStopTempco;
  data->s.vShutdownStartTempco = dataToStore->changedData.vShutdownStartTempco;
  data->s.vShutdownStopTempco = dataToStore->changedData.vShutdownStopTempco;
  data->s.balancerVoltageTempco = dataToStore->changedData.balancerVoltageTempco;
  savedLockKey =  dataToStore->changedData.lockKey;
  if (savedLockKey != 0) sysData.s.writeLocked = 1 ;
  //  Geräteinformation
  data->s.deviceSn = dataToStore->deviceInfo.SN;
 

  // prüfe Eeprom Status Infos
  if(dataToStore->eepromState.structureSize != sizeof(eeprom_stored_data_t)) return HAL_ERROR;
  if(dataToStore->eepromState.revisionInfo != 0) return HAL_ERROR;
  if(dataToStore->eepromState.firstStartId != FIRST_START_ID) return HAL_ERROR;

  return HAL_OK;
}



HAL_StatusTypeDef EEPROM_readLogData()
{
  log_data_t * logData;

  /****************WERTE_AUS_FLASH_LESEN********************/
  
  
  if(getEEPROMData(USER_EEPROM_BASE_ADRESS + FLASH_PAGE_SIZE, (uint8_t *)eepromLogData, sizeof(eepromLogData)) != HAL_OK) return HAL_ERROR;

  logData = (log_data_t *) eepromLogData;  
  sysData.s.cycleCounter = logData->cycleCounter;
  sysData.s.maxVoltage = logData->maxVoltage;  
  sysData.s.minVoltage = logData->minVoltage;
  sysData.s.maxTemperature = logData->maxVoltage;
  sysData.s.minTemperature = logData->minTemperature;
  sysData.s.criticalOverVoltageTime = logData->criticalOvervoltageTime;
  sysData.s.criticalUnderVoltageTime = logData->criticalUndervoltageTime;
  sysData.s.criticalOverTempTime = logData->criticalOverTempTime;
  sysData.s.criticalUnderTempTime = logData->criticalUnderTempTime;  

  return HAL_OK;
}
