
#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