#ifndef __I2C_HELPER_H
#define __I2C_HELPER_H
/**
* 封装 Master模式  
*/

#ifdef __cplusplus
	extern "C" {
#endif

#include "i2c.h"
#include <stdlib.h>
/*  回调函数，将数据返回上层 */
typedef void (*it_callback)(void *obj,uint8_t *buf, uint32_t buf_size );

/* 由于可能存在多个外设，考虑将 事件类型封装在helper, 事件定义初始化不必放这里*/
typedef enum
{
   I2C_HELPER_Event_READY,                   /*!< Startup finished. */
   I2C_HELPER_Event_INIT,                  
   I2C_HELPER_Event_INIT_SUCCESS,                  
   I2C_HELPER_Event_TRANS_ONLY,                  
   I2C_HELPER_Event_TRANS_FOR_DATA,                 
   I2C_HELPER_Event_DATA_RCV,                 
} I2C_HELPER_Event_TypeDef;

typedef enum 
{
	I2C_HELPER_TRANS_POLLING,
	I2C_HELPER_TRANS_IT,
	I2C_HELPER_TRANS_DMA
}I2C_HELPER_TRANS_TypeDef;

typedef enum 
{
	I2C_HELPER_RCV_POLLING,
	I2C_HELPER_RCV_IT,
	I2C_HELPER_RCV_DMA
}I2C_HELPER_RCV_TypeDef;

typedef enum 
{
	I2C_HELPER_MODE_MASTER,
	I2C_HELPER_MODE_SLAVE
}I2C_HELPER_MODE_TypeDef;

typedef struct 
{
    I2C_HandleTypeDef *hi2c;
	uint8_t i2c_write_address;
	uint8_t i2c_read_address;
	I2C_HELPER_TRANS_TypeDef trans_type;  /* 0 :polling, 1: IT  2: DMA*/
    I2C_HELPER_RCV_TypeDef rcv_type;  /* 0 :polling, 1: IT  2: DMA*/
	I2C_HELPER_MODE_TypeDef mode;   

    uint8_t *trans_buf;
    volatile uint32_t trans_size;
    volatile uint32_t trans_data_con;

    uint8_t *receive_buf;
    volatile uint32_t receive_size;
    volatile uint8_t receive_data_con;
 
    // volatile uint8_t receive_buf_con;
    // uint32_t receive_buf_half_len;
    // uint8_t half_flag;  /*0 : 未半满， 1：半满， 2： 半满已经处理*/

    // volatile Uart_Status_TypeDef status;  /* 发送状态 0: ready , 1：正在发送 busy，2：发送ok，*/

    void * obj;
    it_callback callback;


}I2CHelper_TypeDef;

I2CHelper_TypeDef * I2CHelper_Init( );
void I2CHelper_Set_Hi2c( I2CHelper_TypeDef *i2chelper,  I2C_HandleTypeDef * hi2c  );
void I2CHelper_Set_Mode( I2CHelper_TypeDef *i2chelper,  I2C_HELPER_MODE_TypeDef mode  );
void I2CHelper_Set_Trans_Type( I2CHelper_TypeDef *i2chelper,  I2C_HELPER_TRANS_TypeDef trans_type  );
void I2CHelper_Set_Rcv_Type( I2CHelper_TypeDef *i2chelper,  I2C_HELPER_RCV_TypeDef rcv_type  );
 
// void I2CHelper_Set_timeout( I2CHelper_TypeDef *i2chelper,  uint32_t timeout_ms  );

int I2CHelper_Set_callback_func_obj( I2CHelper_TypeDef *i2chelper,   void * obj,  it_callback callback );

void I2CHelper_Set_rcv_buf( I2CHelper_TypeDef *i2chelper, uint8_t *buf, uint32_t buf_size );
void I2CHelper_Set_Trans_Buf( I2CHelper_TypeDef *i2chelper, uint8_t *buf, uint32_t buf_size );

int I2CHelper_Write( I2CHelper_TypeDef *i2chelper,  uint8_t * buf, uint16_t size);
int I2CHelper_Read(I2CHelper_TypeDef *i2chelper,  uint8_t * buf, uint16_t size);

void I2CHelper_Snd_Cplt_Callback(   );
void I2CHelper_Rcv_Cplt_Callback(   );

// int I2CHelper_Flags_Set(I2CHelper_TypeDef *i2chelper,  I2C_HELPER_Event_TypeDef evt_type );
// int I2CHelper_Flags_Clear(I2CHelper_TypeDef *i2chelper,  I2C_HELPER_Event_TypeDef evt_type );
// int I2CHelper_Flags_Wait(I2CHelper_TypeDef *i2chelper,  I2C_HELPER_Event_TypeDef evt_type );


// void I2CHelper_Set_GPIO_For_Trans_Cplt(  I2CHelper_TypeDef *i2chelper );
// void I2CHelper_Rcv_Cplt_Callback( I2CHelper_TypeDef *i2chelper  );
// void I2CHelper_Rcv_Idle_Callback( I2CHelper_TypeDef *i2chelper  );
// void I2CHelper_Rcv_DMA_Half_Callback( I2CHelper_TypeDef *i2chelper  );

int I2CHelper_copy( I2CHelper_TypeDef *i2chelper, uint8_t *buf, uint32_t buf_size );
int I2CHelper_isbusy( I2CHelper_TypeDef *i2chelper );
void I2CHelper_error( I2CHelper_TypeDef *i2chelper );
 

// uint16_t Get_Crc16(const char *buf, uint16_t len);
// uint8_t Check_Crc16(uint8_t *buf, uint16_t length); 
#ifdef __cplusplus
	}
#endif

#endif

 