/*
 * eeprom.h
 *
 *  Created on: 2020. 4. 22.
 *      Author: parkyj
 */

#ifndef EEPROM_H_
#define EEPROM_H_


#define EEPROM_M24C08_ID                  0xA0
#define EEPROM_Block0_ADDRESS             EEPROM_M24C08_ID
#define EEPROM_ATT_BASE					  0x0000 + 96

#if 0 // PYJ.2020.04.25_BEGIN --

#define EEPROM_ATT_DL1_TABLE_ADDRESDS	 (( EEPROM_ATT_BASE                 +(sizeof(ATT_TABLE_st))   )  & 0xFFFF) //128
#define EEPROM_ATT_DL2_TABLE_ADDRESDS	 (( EEPROM_ATT_DL1_TABLE_ADDRESDS  + (sizeof(ATT_TABLE_st))  ) & 0xFFFF) 
#define EEPROM_ATT_DL3_TABLE_ADDRESDS	 (( EEPROM_ATT_DL2_TABLE_ADDRESDS  + (sizeof(ATT_TABLE_st))  ) & 0xFFFF)
#define EEPROM_ATT_DL4_TABLE_ADDRESDS	 (( EEPROM_ATT_DL3_TABLE_ADDRESDS  + (sizeof(ATT_TABLE_st))  ) & 0xFFFF)
#define EEPROM_ATT_UL1_TABLE_ADDRESDS	 (( EEPROM_ATT_DL4_TABLE_ADDRESDS  + (sizeof(ATT_TABLE_st))  )    & 0xFFFF)
#define EEPROM_ATT_UL2_TABLE_ADDRESDS	 (( EEPROM_ATT_UL1_TABLE_ADDRESDS  + (sizeof(ATT_TABLE_st))  )    & 0xFFFF)
#define EEPROM_ATT_UL3_TABLE_ADDRESDS	 (( EEPROM_ATT_UL2_TABLE_ADDRESDS  + (sizeof(ATT_TABLE_st))  )    & 0xFFFF)
#define EEPROM_ATT_UL4_TABLE_ADDRESDS	 (( EEPROM_ATT_UL3_TABLE_ADDRESDS  + (sizeof(ATT_TABLE_st))  )    & 0xFFFF)//128
#define EEPROM_DET_DL1_TABLE_ADDRESDS	 (( EEPROM_ATT_UL4_TABLE_ADDRESDS  + (sizeof(DET_TABLEDL_st)+ 2))    & 0xFFFF)
#define EEPROM_DET_DL2_TABLE_ADDRESDS	 (( EEPROM_DET_DL1_TABLE_ADDRESDS  + (sizeof(DET_TABLEDL_st)+ 2))    & 0xFFFF)
#define EEPROM_DET_DL3_TABLE_ADDRESDS	 (( EEPROM_DET_DL2_TABLE_ADDRESDS  + (sizeof(DET_TABLEDL_st)+ 2))    & 0xFFFF)
#define EEPROM_DET_DL4_TABLE_ADDRESDS	 (( EEPROM_DET_DL3_TABLE_ADDRESDS  + (sizeof(DET_TABLEDL_st)+ 2))    & 0xFFFF)
#define EEPROM_DET_UL1_TABLE_ADDRESDS	 (( EEPROM_DET_DL4_TABLE_ADDRESDS  + (sizeof(DET_TABLEUL_st) + 4))     & 0xFFFF)
#define EEPROM_DET_UL2_TABLE_ADDRESDS	 (( EEPROM_DET_UL1_TABLE_ADDRESDS  + (sizeof(DET_TABLEUL_st)+ 4))     & 0xFFFF)
#define EEPROM_DET_UL3_TABLE_ADDRESDS	 (( EEPROM_DET_UL2_TABLE_ADDRESDS  + (sizeof(DET_TABLEUL_st)+ 4))     & 0xFFFF)
#define EEPROM_DET_UL4_TABLE_ADDRESDS	 (( EEPROM_DET_UL3_TABLE_ADDRESDS  + (sizeof(DET_TABLEUL_st)+ 4))     & 0xFFFF)
#define EEPROM_TEMP_DL1_TABLE_ADDRESDS	 (( EEPROM_DET_UL4_TABLE_ADDRESDS  + (sizeof(TEMP_TABLE_st)+12))     & 0xFFFF)
#define EEPROM_TEMP_DL2_TABLE_ADDRESDS	 (( EEPROM_TEMP_DL1_TABLE_ADDRESDS +( sizeof(TEMP_TABLE_st)+12))     & 0xFFFF)
#define EEPROM_TEMP_DL3_TABLE_ADDRESDS	 (( EEPROM_TEMP_DL2_TABLE_ADDRESDS +( sizeof(TEMP_TABLE_st)+12))     & 0xFFFF)
#define EEPROM_TEMP_DL4_TABLE_ADDRESDS	 (( EEPROM_TEMP_DL3_TABLE_ADDRESDS +( sizeof(TEMP_TABLE_st)+12))     & 0xFFFF)
#define EEPROM_TEMP_UL1_TABLE_ADDRESDS	 (( EEPROM_TEMP_DL4_TABLE_ADDRESDS +( sizeof(TEMP_TABLE_st)+12))     & 0xFFFF)
#define EEPROM_TEMP_UL2_TABLE_ADDRESDS	 (( EEPROM_TEMP_UL1_TABLE_ADDRESDS +( sizeof(TEMP_TABLE_st)+12))     & 0xFFFF)
#define EEPROM_TEMP_UL3_TABLE_ADDRESDS	 (( EEPROM_TEMP_UL2_TABLE_ADDRESDS +( sizeof(TEMP_TABLE_st)+12))     & 0xFFFF)
#define EEPROM_TEMP_UL4_TABLE_ADDRESDS	 (( EEPROM_TEMP_UL3_TABLE_ADDRESDS +( sizeof(TEMP_TABLE_st)+12))     & 0xFFFF)
#define EEPROM_USER_ATTEN_VALUE_ADDRESDS (( EEPROM_TEMP_UL4_TABLE_ADDRESDS +( sizeof(USER_ATTEN_st)+16))     & 0xFFFF)
#define EEPROM_WINDOW_STATUS_ADDRESDS	 ((EEPROM_USER_ATTEN_VALUE_ADDRESDS + (sizeof(BLUESTATUS_st))) & 0xFFFF) //96byte


#define EEPROM_WINDOW_STATUS_ADDRESDS	 ((EEPROM_ATT_BASE + (sizeof(BLUESTATUS_st))) & 0xFFFF) //96byte
#define EEPROM_ATT_DL1_TABLE_ADDRESDS	 (( EEPROM_WINDOW_STATUS_ADDRESDS  + (sizeof(ATT_TABLE_st))  )& 0xFFFF) //128
#define EEPROM_ATT_DL2_TABLE_ADDRESDS	 (( EEPROM_ATT_DL1_TABLE_ADDRESDS  + (sizeof(ATT_TABLE_st))  ) & 0xFFFF) 
#define EEPROM_ATT_DL3_TABLE_ADDRESDS	 (( EEPROM_ATT_DL2_TABLE_ADDRESDS  + (sizeof(ATT_TABLE_st))  ) & 0xFFFF)
#define EEPROM_ATT_DL4_TABLE_ADDRESDS	 (( EEPROM_ATT_DL3_TABLE_ADDRESDS  + (sizeof(ATT_TABLE_st))  ) & 0xFFFF)
#define EEPROM_ATT_UL1_TABLE_ADDRESDS	 (( EEPROM_ATT_DL4_TABLE_ADDRESDS  + (sizeof(ATT_TABLE_st))  )    & 0xFFFF)
#define EEPROM_ATT_UL2_TABLE_ADDRESDS	 (( EEPROM_ATT_UL1_TABLE_ADDRESDS  + (sizeof(ATT_TABLE_st))  )    & 0xFFFF)
#define EEPROM_ATT_UL3_TABLE_ADDRESDS	 (( EEPROM_ATT_UL2_TABLE_ADDRESDS  + (sizeof(ATT_TABLE_st))  )    & 0xFFFF)
#define EEPROM_ATT_UL4_TABLE_ADDRESDS	 (( EEPROM_ATT_UL3_TABLE_ADDRESDS  + (sizeof(ATT_TABLE_st))  )    & 0xFFFF)//128
#define EEPROM_DET_DL1_TABLE_ADDRESDS	 (( EEPROM_ATT_UL4_TABLE_ADDRESDS  + (sizeof(DET_TABLEDL_st)))    & 0xFFFF)
#define EEPROM_DET_DL2_TABLE_ADDRESDS	 (( EEPROM_DET_DL1_TABLE_ADDRESDS  + (sizeof(DET_TABLEDL_st)))    & 0xFFFF)
#define EEPROM_DET_DL3_TABLE_ADDRESDS	 (( EEPROM_DET_DL2_TABLE_ADDRESDS  + (sizeof(DET_TABLEDL_st)))    & 0xFFFF)
#define EEPROM_DET_DL4_TABLE_ADDRESDS	 (( EEPROM_DET_DL3_TABLE_ADDRESDS  + (sizeof(DET_TABLEDL_st)))    & 0xFFFF)
#define EEPROM_DET_UL1_TABLE_ADDRESDS	 (( EEPROM_DET_DL4_TABLE_ADDRESDS  + (sizeof(DET_TABLEUL_st)))     & 0xFFFF)
#define EEPROM_DET_UL2_TABLE_ADDRESDS	 (( EEPROM_DET_UL1_TABLE_ADDRESDS  + (sizeof(DET_TABLEUL_st)))     & 0xFFFF)
#define EEPROM_DET_UL3_TABLE_ADDRESDS	 (( EEPROM_DET_UL2_TABLE_ADDRESDS  + (sizeof(DET_TABLEUL_st)))     & 0xFFFF)
#define EEPROM_DET_UL4_TABLE_ADDRESDS	 (( EEPROM_DET_UL3_TABLE_ADDRESDS  + (sizeof(DET_TABLEUL_st)))     & 0xFFFF)
#define EEPROM_TEMP_DL1_TABLE_ADDRESDS	 (( EEPROM_DET_UL4_TABLE_ADDRESDS  + (sizeof(TEMP_TABLE_st)))     & 0xFFFF)
#define EEPROM_TEMP_DL2_TABLE_ADDRESDS	 (( EEPROM_TEMP_DL1_TABLE_ADDRESDS +( sizeof(TEMP_TABLE_st)))     & 0xFFFF)
#define EEPROM_TEMP_DL3_TABLE_ADDRESDS	 (( EEPROM_TEMP_DL2_TABLE_ADDRESDS +( sizeof(TEMP_TABLE_st)))     & 0xFFFF)
#define EEPROM_TEMP_DL4_TABLE_ADDRESDS	 (( EEPROM_TEMP_DL3_TABLE_ADDRESDS +( sizeof(TEMP_TABLE_st)))     & 0xFFFF)
#define EEPROM_TEMP_UL1_TABLE_ADDRESDS	 (( EEPROM_TEMP_DL4_TABLE_ADDRESDS +( sizeof(TEMP_TABLE_st)))     & 0xFFFF)
#define EEPROM_TEMP_UL2_TABLE_ADDRESDS	 (( EEPROM_TEMP_UL1_TABLE_ADDRESDS +( sizeof(TEMP_TABLE_st)))     & 0xFFFF)
#define EEPROM_TEMP_UL3_TABLE_ADDRESDS	 (( EEPROM_TEMP_UL2_TABLE_ADDRESDS +( sizeof(TEMP_TABLE_st)))     & 0xFFFF)
#define EEPROM_TEMP_UL4_TABLE_ADDRESDS	 (( EEPROM_TEMP_UL3_TABLE_ADDRESDS +( sizeof(TEMP_TABLE_st)))     & 0xFFFF)

#endif // PYJ.2020.04.25_END -- 



#define MAKE_ADDRESS(_addr, _e2)            ((uint8_t)EEPROM_M24C08_ADDR | \
                                             ((_e2) ? EEPROM_M24C08_ADDR_E2 : 0) | \
                                             ((uint8_t)((_addr) >> 7) & EEPROM_M24C08_BYTE_ADDR_H))

#define EEPROM_M24C08_ADDR                  0xA0        //!< M24C08 device identifier
#define EEPROM_M24C08_ADDR_E2               0x08        //!< M24C08 E2 address bit




#define EEPROM_M24C08_BYTE_ADDR_H           0x06

HAL_StatusTypeDef EEPROM_M24C08_Read(uint8_t devid,uint16_t Address,uint8_t* data,uint16_t size);
HAL_StatusTypeDef EEPROM_M24C08_write(uint8_t devid,uint16_t Address,uint8_t* data,uint16_t size);

HAL_StatusTypeDef EEPROM_M24C08_ByteRead(uint16_t devid,uint16_t Address,uint8_t* data,uint8_t size);
HAL_StatusTypeDef EEPROM_M24C08_Bytewrite(uint16_t devid,uint16_t Address,uint8_t* data,uint8_t size);
HAL_StatusTypeDef EEPROM_M24C08_Zerowrite(uint8_t devid,uint16_t Address);

void EEPROM_M24C08_Init(void);















// Exported type definitions --------------------------------------------------
/**
 * The possible states the EEPROM driver can be in.
 */
typedef enum
{
    EE_UNINIT = 0,      //!< Driver has not been initialized
    EE_IDLE,            //!< Driver has been initialized and is ready to start a transfer
    EE_FINISH,          //!< Driver has finished with a transfer
    EE_READ,            //!< Driver is doing a read operation
    EE_WRITE_SEND,      //!< Driver is writing data
    EE_WRITE_WAIT       //!< Driver is waiting for the EEPROM to finish a write cycle
} EEPROM_Status;

/**
 * The possible outcomes of an operation.
 */
typedef enum
{
    EE_OK = 0,      //!< Indicates success
    EE_BUSY,        //!< Indicates that the driver is currently busy doing a transfer
    EE_ERROR        //!< Indicates an error condition
} EEPROM_Error;

/**
 * Contains static configuration for the board such as populated peripherals, fitted resistor values and Ethernet MAC
 * address, that are stored on the EEPROM.
 */

// Macros ---------------------------------------------------------------------

#ifndef LOBYTE
#define LOBYTE(x)  ((uint8_t)(x & 0x00FF))
#endif
#ifndef HIBYTE
#define HIBYTE(x)  ((uint8_t)((x & 0xFF00) >> 8))
#endif
#define MAKE_ADDRESS(_addr, _e2)            ((uint8_t)EEPROM_M24C08_ADDR | \
                                             ((_e2) ? EEPROM_M24C08_ADDR_E2 : 0) | \
                                             ((uint8_t)((_addr) >> 7) & EEPROM_M24C08_BYTE_ADDR_H))

// Constants ------------------------------------------------------------------

/**
 * @defgroup EEPROM_M24C08_ADDRESS M24C08 Address definitions
 * 
 * The address byte that is sent to an M24C08 consists of 4 parts:
 *  + The device identifier {@link EEPROM_M24C08_ADDR} (4 bits)
 *  + An address bit {@link EEPROM_M24C08_ADDR_E2} that is either set or not, depending on the value of the `E2` pin on
 *    the M24C08 device
 *  + The two most significant bits of the memory address to be read/written {@link EEPROM_M24C08_BYTE_ADDR_H}
 *  + The standard I2C read/write bit
 * @{
 */
#define EEPROM_M24C08_ADDR                  0xA0        //!< M24C08 device identifier
#define EEPROM_M24C08_ADDR_E2               0x08        //!< M24C08 E2 address bit
/**
 * Bitmask for the M24C08 I2C Address bits that are used for the high byte of the memory address. The address bits are
 * either the high byte shifted left by one or the 16 bit address shifted right by 7 and then masked.
 */
#define EEPROM_M24C08_BYTE_ADDR_H           0x06
/** @} */

/**
 * Timeout in ms for I2C communication
 */
#define EEPROM_I2C_TIMEOUT                  0x200

/**
 * EEPROM size in bytes
 */
#define EEPROM_SIZE                         0x400

/**
 * Mask for the page address, a page write can only write to addresses which have the same page address
 */
#define EEPROM_PAGE_MASK                    0x03F0

/**
 * Page size of the EEPROM, only one page can be written at a time
 */
#define EEPROM_PAGE_SIZE                    0x10

/**
 * Configuration data offset, that is the first address of the configuration data space
 */
#define EEPROM_CONFIG_OFFSET                0

/**
 * Size of the configuration data section in bytes
 */
#define EEPROM_CONFIG_SIZE                  128

/**
 * Data offset, that is the first address for arbitrary data
 */
#define EEPROM_DATA_OFFSET                  0x80

/**
 * Size of the data section in bytes, this is the EEPROM size minus the data offset
 */
#define EEPROM_DATA_SIZE                    (EEPROM_SIZE - EEPROM_DATA_OFFSET)

/**
 * Size of the settings buffer in bytes
 */
#define EEPROM_SETTINGS_SIZE                64

// Exported functions ---------------------------------------------------------



// ----------------------------------------------------------------------------


#endif /* EEPROM_H_ */
