#ifndef EEPROM_H_
#define EEPROM_H_
/*
* 两种方法:
* 一种直接调用读写多字节, 多任务下可能导致阻塞
* 一种设置size  send_buf 实现
*/
#include "main.h"
 
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"
#include "bsp_i2c.h"
#include "elog.h"

#define EEPROM_BYTE_DELAY_ENABLE 1
#define EEPROM_WRITE_ADDRESS 0xA0
#define EEPROM_READ_ADDRESS 0xA1

typedef enum {
    EEPROM_EVT_WRITE,
    EEPROM_EVT_READ,
    EEPROM_EVT_WRITE_BYTE_DELAY,
}EEPROM_EVT_TypeDef;

typedef enum {
    EEPROM_STATE_READY,
    EEPROM_STATE_WRITE,
    EEPROM_STATE_READ,
}EEPROM_STATE_TypeDef;

typedef enum  {
    EEPROM_MEM_ADDR_TYPE_Bit8,
    EEPROM_MEM_ADDR_BIT_TYPE_Bit16,
}EEPROM_MEM_ADDR_TypeDef;

typedef enum  {
    EEPROM_MEM_ADDR_BIT_8,
    EEPROM_MEM_ADDR_BIT_16,
}EEPROM_MEM_ADDR_BIT_TypeDef;

typedef enum  {
    EEPROM_DEV_ADDR_BIT_8,
    EEPROM_DEV_ADDR_BIT_10,
} EEPROM_DEV_ADDR_TypeDef;

typedef enum { 
    AT24C01     =127,    // 8bit mem_addr
    AT24C02     =255,
    AT24C04     =511,    // 16bit mem_addr,先发  high8 后 low8
    AT24C08     =1023,
    AT24C16     =2047,
    AT24C32     =4095,
    AT24C64     =8191,
    AT24C128    =16383,
    AT24C256    =32767, 
}EEPROM_MODEL_TypeDef;

// typedef void (*read_callback)();
// typedef void (*write_callback)();

extern I2C_HELPER_TypeDef *eeprom_helper;

typedef enum {
   EEPROM_WORK_STATE_WAITING,
   EEPROM_WORK_STATE_READY,
   EEPROM_WORK_STATE_Writing,
   EEPROM_WORK_STATE_WRITE_Waiting,
   EEPROM_WORK_STATE_Reading,
   EEPROM_WORK_STATE_ERROR,
   EEPROM_WORK_STATE_STOP
}EEPROM_WORK_STATE_TypeDef;

typedef struct
{
    void (*init)(void);
    void (*port)(void) ;
    int  (*test)(void);
 
    EEPROM_MODEL_TypeDef    model;       //  AT24C01  AT24C02  AT24C256
    uint16_t     mem_addr_size;     
    EEPROM_DEV_ADDR_TypeDef     dev_addr;          
    uint8_t     page_addr;
    uint8_t     write_delay_ms;
        uint32_t size;
    uint8_t *buf;
    volatile EEPROM_WORK_STATE_TypeDef state;
}My_EEPROM_TypeDef;

extern My_EEPROM_TypeDef my_eeprom;

void Eeprom_Init(  );

void Eeprom_Port(  );
void Eeprom_Task(  );
int Eeprom_Test( void );

int Eeprom_callback(My_EEPROM_TypeDef *pEeprom, uint8_t *buf, uint16_t size);

// int Eeprom_SET_WorkMode( uint16_t mem_addr_type);
int Eeprom_SET_Device_Model(EEPROM_MODEL_TypeDef model);
int Eeprom_SET_Write_Delay_ms(  uint8_t write_delay_ms);

// int Eeprom_Transmit(EEPROM_TypeDef *eeprom,  uint8_t * buf, uint16_t size);
// int Eeprom_Begin_Rcv(EEPROM_TypeDef *eeprom,  uint8_t * buf, uint16_t size);

int Eeprom_Read( uint8_t * buf, uint16_t size );
int Eeprom_Write(  uint8_t * buf, uint16_t size );

// void Eeprom_Set_Sendbuf_Size(EEPROM_TypeDef *eeprom,  uint8_t * buf, uint16_t size);


// #ifdef EEPROM_BYTE_DELAY_ENABLE
// int Eeprom_Write_By_Byte_Delay(EEPROM_TypeDef *eeprom,  uint8_t * buf, uint16_t size);

// int Eeprom_callback(My_EEPROM_TypeDef *pEeprom, uint8_t *buf, uint16_t size);

// #endif
 
#endif

 




/**
 * 
 * @brief 用非阻塞方法写 EEPROM  会写不进去--> 写数据到EEPROM,每个字节加5-8ms 延时
 * 还是用阻塞的方法区写， 读可以考虑非阻塞  -->  IT   DMA 
 * 不用 i2chelper  直接用hi2c,  
 * 
 * Eeprom_SET_Mem_Addr   设置eeprom数据地址
 * Eeprom_Set_Sendbuf_Size  设置buf  size 进行写入 EEprom
 * 
 * 读取
 * Eeprom_SET_Mem_Addr  设置eeprom数据地址
 * HAL_I2C_Mem_Read
 * @details 
 * 
 *  uint8_t   buf1[4] ={0x05, 0x03 , 0x04, 0x05};
    uint8_t   buf2[4] = {0x08,0x08,0x08,0x08} ;
    int st;
    // Eeprom_Set_Sendbuf_Size(eeprom, buf1, 4);
    // my_eeprom.port();
    Eeprom_SET_Mem_Addr( eeprom, 0 );
    st = HAL_I2C_Mem_Write(eeprom->hi2c, eeprom->dev_addr, eeprom->mem_addr, eeprom->mem_addr_type, buf1, 4, eeprom->write_delay_ms);
    osDelay( 10 );
    // Eeprom_Read( eeprom,  buf2, 4);
    // st = HAL_I2C_Mem_Read(eeprom->hi2c, eeprom->dev_addr, eeprom->mem_addr, eeprom->mem_addr_type, buf2, 4, eeprom->write_delay_ms);

    Eeprom_SET_Mem_Addr( eeprom, 0 );
    if ( Eeprom_Read(eeprom, buf2, 4) != 0 ) 
    {
        log_i(" Eeprom Read Config Error ");
    }else{
        log_i(" Eeprom Read Config OK! ");
    }

    osDelay(10);
    log_i( "buf2  %d   %d ", buf2[0] , buf2[1]);

      uint8_t  buf1[24] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x04, 0x44, 0x09,0x01, 0x03, 0x00, 0x00, 0x00, 0x04, 0x44, 0x09,0x01, 0x03, 0x00, 0x00, 0x00, 0x04, 0x44, 0x09};
    uint8_t  buf2[24] ={0};
    my_eeprom.buf =  buf1;
    my_eeprom.size =  24;
    my_eeprom.state =  EEPROM_WORK_STATE_Writing;

    while(my_eeprom.size != 0) { osDelay(2);};
    log_i("write ok....");

    HAL_Delay(200);
    my_eeprom.state =  EEPROM_WORK_STATE_Reading;     
 */
 