#ifndef _EEPROM_24CXX_H_
#define _EEPROM_24CXX_H_

#include "Simulated_IIC_Master.h"

/******************************************************************************
=====================================================
            Supported EEPROM Devices
-----------------------------------------------------
     Device    | Density	| Organization | Page Size
-----------------------------------------------------
 EEPROM_24C01  |  1Kb    |    128  x 8   |    8
 EEPROM_24C02  |  2Kb    |	  256  x 8   |	  8
 EEPROM_24C04  |  4Kb    |	  512  x 8   |    16
 EEPROM_24C08  |  8Kb    |	  1k   x 8   |    16
 EEPROM_24C16  |  16Kb   |	  2k   x 8   |    16
 EEPROM_24C32  |  32Kb   |	  4k   x 8	 |    32
 EEPROM_24C64  |  64Kb   |	  8k   x 8   |    32
 EEPROM_24C128 |  128Kb  |	  16k  x 8   |    64
 EEPROM_24C256 |  256Kb  |	  32k  x 8   |    64
 EEPROM_24C512 |  512Kb  |	  64k  x 8   |    128
 ====================================================
******************************************************************************/

/******************************************************************************
ѡ�õ�EEPROM
******************************************************************************/
#define   EEPROM_24C16

/******************************************************************************
EEPROMд����ʹ��
******************************************************************************/
#define   EEPROM_WP_ENABLE                  0

#if       EEPROM_WP_ENABLE
#ifndef     EEPROM_WP
#define   EEPROM_WP
#endif
#endif

/******************************************************************************
EEPROM��д��������С
******************************************************************************/
#define   EEPROM_BUFFER_SIZE                32

/******************************************************************************
EEPROM����Ԥ����
******************************************************************************/
#define   EEPROM_DEVICE_ADDR_WR             0xA0
#define   EEPROM_DEVICE_ADDR_RD             0xA1

#if   defined EEPROM_24C01                  /*** 24C01 ***/
#define EEPROM_DATA_ADDR_1_BYTE
#define EEPROM_MAX_DATA_ADDR              0x007F
#define EEPROM_TOTAL_PAGE_NUM             16
#define EEPROM_PAGE_SIZE                  8

#elif defined EEPROM_24C02                  /*** 24C02 ***/
#define EEPROM_DATA_ADDR_1_BYTE
#define EEPROM_MAX_DATA_ADDR              0x00FF
#define EEPROM_TOTAL_PAGE_NUM             32
#define EEPROM_PAGE_SIZE                  8

#elif defined EEPROM_24C04                  /*** 24C04 ***/
#define EEPROM_DATA_ADDR_2_BYTE_MIXED
#define EEPROM_MAX_DATA_ADDR              0x01FF
#define EEPROM_TOTAL_PAGE_NUM             32
#define EEPROM_PAGE_SIZE                  16

#elif defined EEPROM_24C08                  /*** 24C08 ***/
#define EEPROM_DATA_ADDR_2_BYTE_MIXED
#define EEPROM_MAX_DATA_ADDR              0x03FF
#define EEPROM_TOTAL_PAGE_NUM             64
#define EEPROM_PAGE_SIZE                  16

#elif defined EEPROM_24C16                  /*** 24C16 ***/
#define EEPROM_DATA_ADDR_2_BYTE_MIXED
#define EEPROM_MAX_DATA_ADDR              0x07FF
#define EEPROM_TOTAL_PAGE_NUM             128
#define EEPROM_PAGE_SIZE                  16

#elif defined EEPROM_24C32                  /*** 24C32 ***/
#define EEPROM_DATA_ADDR_2_BYTE
#define EEPROM_MAX_DATA_ADDR              0x0FFF
#define EEPROM_TOTAL_PAGE_NUM             128
#define EEPROM_PAGE_SIZE                  32

#elif defined EEPROM_24C64                  /*** 24C64 ***/
#define EEPROM_DATA_ADDR_2_BYTE
#define EEPROM_MAX_DATA_ADDR              0x1FFF
#define EEPROM_TOTAL_PAGE_NUM             256
#define EEPROM_PAGE_SIZE                  32

#elif defined EEPROM_24C128                 /*** 24C128 ***/
#define EEPROM_DATA_ADDR_2_BYTE
#define EEPROM_MAX_DATA_ADDR              0x3FFF
#define EEPROM_TOTAL_PAGE_NUM             256
#define EEPROM_PAGE_SIZE                  64

#elif defined EEPROM_24C256                 /*** 24C256 ***/
#define EEPROM_DATA_ADDR_2_BYTE
#define EEPROM_MAX_DATA_ADDR              0x7FFF
#define EEPROM_TOTAL_PAGE_NUM             512
#define EEPROM_PAGE_SIZE                  64

#elif defined EEPROM_24C512                 /*** 24C512 ***/
#define EEPROM_DATA_ADDR_2_BYTE
#define EEPROM_MAX_DATA_ADDR              0xFFFF
#define EEPROM_TOTAL_PAGE_NUM             512
#define EEPROM_PAGE_SIZE                  128

#else                                       /*** EEPROM��� ***/
#error  EEPROM device is undefined

#endif

/******************************************************************************
EEPROM�����
******************************************************************************/
#define   EEPROM_IDLE                       0x00
#define   EEPROM_WR                         0x10
#define   EEPROM_RD                         0x20

#define   EEPROM_WR_START                   0x10
#define   EEPROM_WR_ADDR                    0x11
#define   EEPROM_WR_DATA                    0x12
#define   EEPROM_WR_STOP                    0x13

#define   EEPROM_RD_START                   0x20
#define   EEPROM_RD_ADDR1                   0x21
#define   EEPROM_RD_RESTART                 0x22
#define   EEPROM_RD_ADDR2                   0x23
#define   EEPROM_RD_DATA                    0x24
#define   EEPROM_RD_STOP                    0x25

/******************************************************************************
״̬�б�
******************************************************************************/
/*** ����� ***/
typedef enum
{
  EEPROM_OK = 0,                       //�����ɹ�,û�д�����
  EEPROM_BUSY,                         //EEPROMæ
  EEPROM_INVALID_DEVICE_ADDR,          //��Ч��������ַ
  EEPROM_INVALID_DATA_ADDR,            //��Ч�����ݵ�ַ
  EEPROM_DATA_LENGTH_ERR,              //��������ݳ���
  EEPROM_NO_RESPONSE,                  //EEPROMû����Ӧ
} EEPROMErrEnum;

/*** ����� ***/
typedef enum
{
  EEPROM_RW_IDLE = 0,                  //����״̬,���������ݶ�д
  EEPROM_RW_REQ,                       //�������������д
  EEPROM_RW_BUSY,                      //���ݶ�д������
} EEPROMRWStateEnum;

/*** ���� ***/
typedef enum
{
  EEPROM_RW_NONE = 0,                  //δ�������д
  EEPROM_RW_DONE,                      //���ݶ�д���
  EEPROM_RW_FAIL,                      //���ݶ�дʧ��
  EEPROM_RW_IN_PROGRESS,               //���ݶ�д��
} EEPROMRWResultEnum;

/******************************************************************************
EEPROM��д���ƽṹ
******************************************************************************/
typedef struct
{
  uint8_t             State;
  uint8_t             Cnt;
  uint8_t             WRAddrLen;
  uint8_t             WRAddr[3];
  uint8_t             WRDataLen;
  uint8_t             WRData[EEPROM_BUFFER_SIZE];
  EEPROMRWStateEnum   WRState;
  EEPROMRWResultEnum  WRResult;
  uint8_t             RDAddrLen;
  uint8_t             RDAddr[3];
  uint8_t             RDDataLen;
  uint8_t             RDData[EEPROM_BUFFER_SIZE];
  EEPROMRWStateEnum   RDState;
  EEPROMRWResultEnum  RDResult;
} EEPROMRWStruct;

/******************************************************************************
��������
******************************************************************************/
EEPROMErrEnum EEPROM_Instant_Byte_Write(uint8_t DeviceAddr, uint16_t DataAddr, uint8_t Data);
EEPROMErrEnum EEPROM_Instant_Page_Write(uint8_t DeviceAddr, uint16_t DataAddr, uint8_t *pData, uint8_t Len);
EEPROMErrEnum EEPROM_Byte_Write(uint8_t DeviceAddr, uint16_t DataAddr, uint8_t Data);
EEPROMErrEnum EEPROM_Page_Write(uint8_t DeviceAddr, uint16_t DataAddr, uint8_t *pData, uint8_t Len);
EEPROMRWResultEnum EEPROM_Get_Write_Result(void);
void EEPROM_Write_In(void);

EEPROMErrEnum EEPROM_Instant_Byte_Read(uint8_t DeviceAddr, uint16_t DataAddr, uint8_t *pData);
EEPROMErrEnum EEPROM_Instant_Sequential_Read(uint8_t DeviceAddr, uint16_t DataAddr, uint8_t *pData, uint8_t Len);
EEPROMErrEnum EEPROM_Byte_Read(uint8_t DeviceAddr, uint16_t DataAddr);
EEPROMErrEnum EEPROM_Sequential_Read(uint8_t DeviceAddr, uint16_t DataAddr, uint8_t Len);
EEPROMRWResultEnum EEPROM_Get_Read_Result(void);
uint8_t EEPROM_Get_Read_Out_Byte(void);
void EEPROM_Get_Read_Out(uint8_t *pData, uint8_t Len);
void EEPROM_Read_Out(void);

void EEPROM_Init(void);
void EEPROM_RW_Service(void);

#endif