////////////////////////////////////////////////////////////////////////////////////////////////////
//ANDRUINO LIBRARY
//A.Scavuzzo
//www.andruino.it
// DEVICE
//
//DON'T MODIFY THIS FILE!!!!!!!!!
//DON'T MODIFY THIS FILE!!!!!!!!!
//DON'T MODIFY THIS FILE!!!!!!!!!
//DON'T MODIFY THIS FILE!!!!!!!!!
//DON'T MODIFY THIS FILE!!!!!!!!!
////////////////////////////////////////////////////////////////////////////////////////////////////

/* definition to expand macro then apply to pragma message */
#define VALUE_TO_STRING(x) #x
#define VALUE(x) VALUE_TO_STRING(x)
#define VAR_NAME_VALUE(var) #var "="  VALUE(var)


//###################################
//ESP8266 MCU
//###################################
#if MCU_ESP8266 == 1

#include <EEPROM.h>


void eeprom_write_byteNEW(int addr, uint8_t data) {
  EEPROM.begin(BOARD_EEP_SIZE);
  EEPROM.write(addr, data);
  EEPROM.end();
}

uint8_t eeprom_read_byteNEW(int addr) {
  //begin is mandatory before the read
  EEPROM.begin(BOARD_EEP_SIZE);
  return (EEPROM.read(addr));
}

void eeprom_write_wordNEW(int addr, uint16_t data) {
  EEPROM.begin(BOARD_EEP_SIZE);
  EEPROM.put(addr, data);
  // EEPROM.commit();
  EEPROM.end();
}

uint16_t eeprom_read_wordNEW(int addr) {
  uint16_t data;
  //begin is mandatory before the read
  EEPROM.begin(BOARD_EEP_SIZE);
  EEPROM.get(addr, data);
  return (data);
}


void eeprom_write_dwordNEW(int addr, uint32_t data) {
  EEPROM.begin(BOARD_EEP_SIZE);
  EEPROM.put(addr, data);
  // EEPROM.commit();
  EEPROM.end();
}

uint32_t eeprom_read_dwordNEW(int addr) {
  uint32_t data;
  //begin is mandatory before the read
  EEPROM.begin(BOARD_EEP_SIZE);
  EEPROM.get(addr, data);
  return (data);
}
#define  eeprom_write_blockNEW(x,y,z) EEPROM.begin(BOARD_EEP_SIZE); EEPROM.put(y, x); EEPROM.commit();
#define  eeprom_read_blockNEW(x,y,z) EEPROM.begin(BOARD_EEP_SIZE); EEPROM.get(y, x);



//###################################
//STM32 MCU
//###################################
#elif MCU_STM32 == 1

#include <EEPROM.h>


void eeprom_write_byteNEW(int addr, uint8_t data) {
  //EEPROM.put(addr, data);
  EEPROM.update(addr, data);
}

uint8_t eeprom_read_byteNEW(int addr) {
  byte result;
  //EEPROM.get(addr, result);
  result = EEPROM.read(addr);
  return (result);
}

void eeprom_write_wordNEW(int addr, uint16_t data) {
  EEPROM.put(addr, data);
}

uint16_t eeprom_read_wordNEW(int addr) {
  uint16_t data;
  EEPROM.get(addr, data);
  return (data);
}


void eeprom_write_dwordNEW(int addr, uint32_t data) {
  EEPROM.put(addr, data);
}

uint32_t eeprom_read_dwordNEW(int addr) {
  uint32_t data;
  EEPROM.get(addr, data);
  return (data);
}
#define  eeprom_write_blockNEW(x,y,z)  EEPROM.put(y, x);
#define  eeprom_read_blockNEW(x,y,z)  EEPROM.get(y, x);




//###################################
//AVR MCU (Arduino)
//###################################
#elif ARDUINO_2560MEGA == 1

//ARDUINO UNO AND MEGA
#define  eeprom_read_byteNEW(x) eeprom_read_byte((uint8_t*)(x))
#define  eeprom_read_wordNEW(x) eeprom_read_word((uint16_t*)(x))
#define  eeprom_read_dwordNEW(x) eeprom_read_dword((uint32_t*)(x))

#define  eeprom_write_byteNEW(x,y)  eeprom_update_byte((uint8_t *)(x),(uint8_t)y)
#define  eeprom_write_wordNEW(x,y)  eeprom_update_word((uint16_t *)(x),(uint16_t)y)
#define  eeprom_write_dwordNEW(x,y)  eeprom_update_dword((uint32_t *)(x),(uint32_t)y)

#define  eeprom_write_blockNEW(x,y,z)  eeprom_update_block((void *)x,(void *)y,z)
#define  eeprom_read_blockNEW(x,y,z)  eeprom_read_block((void *)x,(void *)y,z)



//###################################
//SAMD MKR 1010 WIFI
//###################################
#elif ARDUINO_MK1010_WIFI == 1

#include <FlashStorage.h>



#define  read_flash_byte(addr) addr.read()
#define  read_flash_word(addr) addr.read()
#define  read_flash_block(data,addr,len) data = addr.read()

//WRITE
#define  write_flash_byte(addr,data) Serialprintdeepflashln("############WRITE FLASH BYTE############"); addr.write(data)
#define  write_flash_word(addr,data) Serialprintdeepflashln("############WRITE FLASH WORD############"); addr.write(data) 
#define  write_flash_block(data,addr,len) Serialprintdeepflashln("############WRITE FLASH BUFFER############");addr.write(data)


#define  eeprom_read_byteNEW(x) read_flash_byte((x))
#define  eeprom_read_wordNEW(x) read_flash_word((uint16_t*)(x))
#define  eeprom_read_dwordNEW(x) read_flash_word((uint32_t*)(x))

#define  eeprom_write_byteNEW(x,y)  write_flash_byte((uint8_t *)(x),(uint8_t)y)
#define  eeprom_write_wordNEW(x,y)  write_flash_word((uint16_t *)(x),(uint16_t)y)
#define  eeprom_write_dwordNEW(x,y)  write_flash_word((uint32_t *)(x),(uint32_t)y)

#define  eeprom_write_blockNEW(x,y,z)  write_flash_block((void *)x,(void *)y,z)
#define  eeprom_read_blockNEW(x,y,z)  read_flash_block((void *)x,(void *)y,z)

#endif



char AndruinoApp_email_array[40];
char AndruinoApp_PIN_array[5];
char board_name_array[20];
char board_PORT_array[6];

#define SSID_LENGHT 32
#define PASS_LENGHT 32

//************************************************************************************************//
//FLASH LOCATIONS ADDRESS (from 0 to 1023 bytes of EEPROM)
//************************************************************************************************//

//////////////////////////////////////////////
//POWER-ON, VERSION and DATES
#define FLA_POWER_ADDRESS 0                     //only (2 bytes)


#define FLA_DATE_ADDRESS 2              	       //day, hour, min (5,6,7: 3 bytes)

#define FLA_ANDRUINO_PAIRING_ID_ADDRESS 5               //only (8,9: 2 bytes)

#define FLA_CODE_SIGNATURE_ADDRESS 7

#define FLA_ANDRUINO_VERSION 8                 //App version  16 bit (15, 16)

#define FLA_NRF_ENABLE_ADDRESS 10


#define FLA_HTTP_PING_ACTIVE_REQ_EVERY_SEC_ADDRESS 11             //1 bytes
//16 bits
#define FLA_HTTP_PING_REQ_EVERY_SEC_ADDRESS 12                    //2 bytes
//16 bits
#define FLA_HTTP_PING_NOTACTIVE_REQ_EVERY_SEC_ADDRESS 14          //2 bytes


#define FLA_FAULT_RESTART_ADDRESS 16              //only (1 bytes)
#define FLA_SILENT_RESTART_ADDRESS 17             //only (1 bytes)
#define FLA_AP_ENABLED_ADDRESS 18                 //only (1 bytes)
#define FLA_FORCE_CAPTIVE_ADDRESS 19              //only (1 bytes)


#define FLA_PARAM_ADDRESS_OK 40
//40
#define FLA_EMAIL_ADDRESS (FLA_PARAM_ADDRESS_OK+1)
#define FLA_EMAIL_ADDRESS_LAST (FLA_EMAIL_ADDRESS + sizeof(AndruinoApp_email_array)-1)

//5
#define FLA_PIN_ADDRESS (FLA_EMAIL_ADDRESS_LAST +1)
#define FLA_PIN_ADDRESS_LAST (FLA_PIN_ADDRESS + sizeof(AndruinoApp_PIN_array)-1)
//20
#define FLA_BOARD_NAME_ADDRESS (FLA_PIN_ADDRESS_LAST +1)
#define FLA_BOARD_NAME_ADDRESS_LAST (FLA_BOARD_NAME_ADDRESS + sizeof(board_name_array)-1)

//6
#define FLA_PORT_ADDRESS (FLA_BOARD_NAME_ADDRESS_LAST +1)
#define FLA_PORT_ADDRESS_LAST (FLA_PORT_ADDRESS + sizeof(board_PORT_array) -1)


#define FLA_ANDRUINO_IT_IP_OK (FLA_PORT_ADDRESS_LAST +1)
#define FLA_ANDRUINO_IT_IP (FLA_ANDRUINO_IT_IP_OK +1)                                   //20 bytes (92 to 112)
#define FLA_ANDRUINO_IT_IP_LAST (FLA_ANDRUINO_IT_IP + sizeof(andruino_it_ip_address) -1)


//only for wifi
#if WIFI_ESP8266_SHIELD == 1 || MCU_ESP8266 == 1 || ARDUINO_MK1010_WIFI == 1
#define FLA_SSIDWIFI_ADDRESS (FLA_ANDRUINO_IT_IP_LAST +1)
#define FLA_SSIDWIFI_ADDRESS_LAST (FLA_SSIDWIFI_ADDRESS + SSID_LENGHT -1)

#define FLA_PASSWIFI_ADDRESS (FLA_SSIDWIFI_ADDRESS_LAST +2)
#define FLA_PASSWIFI_ADDRESS_LAST (FLA_PASSWIFI_ADDRESS + PASS_LENGHT -1)
#else
#endif



///////////////////////////////////
//Store pin structure on eeprom from 250
#define FLA_STRUCT_START_ADDRESS_OK 250

#define FLA_VAR_START_ADDRESS (FLA_STRUCT_START_ADDRESS_OK + 2)
#define FLA_ANA_START_ADDRESS FLA_VAR_START_ADDRESS + sizeof(Arduino_User_var)
#define FLA_DIG_START_ADDRESS FLA_ANA_START_ADDRESS + sizeof(ArduinoAnalog)
#define FLA_DIG_LAST_ADDRESS FLA_DIG_START_ADDRESS + sizeof(ArduinoIO) - 1


#if NRF24L_ENABLE == 1
//NRF NODE ADDRESS LIST
//from 50 to 70 (10 node, 2 bytes for each node)
#define FLA_NRF_NODE_ADDRESS_OK (FLA_DIG_LAST_ADDRESS +1)
#define FLA_NRF_NODE_ADDRESS FLA_NRF_NODE_ADDRESS_OK                                //2 bytes for each node
#define FLA_NRF_NODE_ADDRESS_LAST (FLA_NRF_NODE_ADDRESS + (NRF24LMaxModules*2) -1)
#define FLA_NRF_START_ADDRESS (FLA_NRF_NODE_ADDRESS_LAST +1)
#define FLA_STRUCT_STOP_ADDRESS_OK FLA_NRF_START_ADDRESS + sizeof(SystemNRF24LPins)
#else
#define FLA_STRUCT_STOP_ADDRESS_OK (FLA_DIG_LAST_ADDRESS +1)
#endif


//////////////////////////////////////////////
//TIMERS (96 bytes, from 940 to 1023)
#define FLA_TIMERS_ADDRESS FLA_STRUCT_STOP_ADDRESS_OK +1              //from 50 to 99 (5 bytes for each timer, 8 timers means 40 bytes)
#define BYTES_FOR_EACH_TIMER 8         	  	                         //each timer uses 8 bytes

#define MAX_TIMERS 12                                               //max number of timers for AVR micro - only 1K of eeprom (max is 12)

#define FLA_LAST_ADDRESS_USED (FLA_TIMERS_ADDRESS + (BYTES_FOR_EACH_TIMER* MAX_TIMERS) -1)

//#if FLA_LAST_ADDRESS_USED > 1023
//#pragma message(VAR_NAME_VALUE(FLA_VAR_START_ADDRESS))
//#error "Timers out of eeprom memory"
//#endif

//#pragma message("FLA_LAST_ADDRESS_USED=" FLA_LAST_ADDRESS_USED)


#if ARDUINO_MK1010_WIFI == 1

FlashStorage(FLA_STATO_ARM_ADDRESS, int);

#endif
