/**
 * @file eeprom.c
 * @author Chen Jihang (embedded@eseaoptics.com)
 * @brief EEPROM驱动
 * @version 1.0
 * @date 2023-01-04
 *
 * @copyright ESEA (c) 2020
 *
 */

#include "eeprom.h"
eeprom_t *eeprom;

eeprom_t *Eeprom_init()
{
    eeprom_t *Handle = (eeprom_t *)malloc(sizeof(eeprom_t));
    if (Handle == NULL)
    {
        return NULL;
    }
    Handle->writeCplt       = 0;
    Handle->readCplt        = 0;
    Handle->write_delay_ms  = 10;
    Handle->size            = 0;
    Handle->WORKMODE        = 1;  /* IT mode*/
    Handle->stat = HAL_I2C_STATE_RESET;  /* HAL_I2C_STATE_RESET 未初始化 */
    return Handle;
}

uint8_t Eeprom_SET_I2C(eeprom_t *eeprom, I2C_HandleTypeDef *i2c)
{
    eeprom->i2c = i2c;
    eeprom->stat = HAL_I2C_STATE_READY;
    return 0;
}
uint8_t Eeprom_SET_Device_Model(eeprom_t *eeprom, uint16_t model)
{
    eeprom->model = model;
    // if (eeprom->model < AT24C16)
    // {
    //     eeprom->mem_addr_type = I2C_MEMADD_SIZE_8BIT;
    // }
    // else
    // {
    //     eeprom->mem_addr_type = I2C_MEMADD_SIZE_16BIT;
    // }
    return 0;
}

uint8_t Eeprom_SET_Device_Addr(eeprom_t *eeprom, uint8_t dev_addr)
{
    eeprom->dev_addr = dev_addr;
    return 0;
}

uint8_t Eeprom_SET_Mem_Addr_Type(eeprom_t *eeprom, uint8_t mem_addr_type)
{
    eeprom->mem_addr_type = mem_addr_type;
    return 0;
}

uint8_t Eeprom_SET_Workmode(eeprom_t *eeprom, uint8_t workmode)
{
    eeprom->WORKMODE = workmode;
    return 0;
}

uint8_t Eeprom_Read_One_Byte(eeprom_t *eeprom, uint16_t mem_addr, uint8_t *buf)
{
    // eeprom->stat = HAL_I2C_Mem_Read_IT(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, 1);
    return HAL_I2C_Mem_Read(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, 1,eeprom->write_delay_ms);
}

uint8_t Eeprom_Write_One_Byte(eeprom_t *eeprom, uint16_t mem_addr, uint8_t *buf)
{
    return HAL_I2C_Mem_Write(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, 1,eeprom->write_delay_ms);

}

uint8_t Eeprom_Read_One_Byte_IT(eeprom_t *eeprom, uint16_t mem_addr, uint8_t *buf)
{
    // eeprom->stat = HAL_I2C_Mem_Read_IT(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, 1);
    eeprom->size  = 0;
    return HAL_I2C_Mem_Read_IT(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, 1 );
}

uint8_t Eeprom_Write_One_Byte_IT(eeprom_t *eeprom, uint16_t mem_addr, uint8_t *buf)
{
    eeprom->size  = 0;
    return HAL_I2C_Mem_Write_IT(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, 1 );
}

uint8_t Eeprom_Read_Multi_Byte(eeprom_t *eeprom, uint16_t mem_addr, uint8_t *buf, uint16_t size, uint32_t timeout )
{
    // eeprom->stat = HAL_I2C_Mem_Write_IT(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, size);
    return HAL_I2C_Mem_Read(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, size,timeout);

}

uint8_t Eeprom_Write_Multi_Byte(eeprom_t *eeprom, uint16_t mem_addr, uint8_t *buf, uint16_t size, uint32_t timeout )
{
    return HAL_I2C_Mem_Write(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, size,timeout);

}

uint8_t Eeprom_Read_Multi_Byte_IT(eeprom_t *eeprom, uint16_t mem_addr, uint8_t *buf, uint16_t size  )
{
    // eeprom->stat = HAL_I2C_Mem_Write_IT(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, size);
    eeprom->stat =HAL_I2C_Mem_Read_IT(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, size );
    // LOG(" readstat %d",eeprom->stat);
    return eeprom->stat;

}

uint8_t Eeprom_Write_Multi_Byte_IT(eeprom_t *eeprom, uint16_t mem_addr, uint8_t *buf, uint16_t size  )
{
    // 写入数据前端循环调用  Eeprom_send_callback
    // return HAL_I2C_Mem_Write_IT(eeprom->i2c, eeprom->dev_addr, mem_addr, eeprom->mem_addr_type, buf, size );
    eeprom->send_buf = buf;
    eeprom->size  = size;
    eeprom->mem_addr = mem_addr;
    return 0;
 
}

/**
 * @brief EEPROM发送回调,须循环调用单字节写入
 *
 * @param eeprom EEPROM描述符
 * @return int 0
 */
uint8_t Eeprom_send(eeprom_t *eeprom)
{
    if (eeprom->size == 0)
    {
        eeprom->send_buf = NULL;
    }
    if (eeprom->send_buf == NULL)
    {
        return 0;
    }
    if ( HAL_I2C_GetState(eeprom->i2c) == 1 )
    {
        return 0;
    }
    if ( (osKernelGetTickCount() -eeprom->time_base) < eeprom->write_delay_ms )
    {
        return 0;
    }
    if ( HAL_I2C_GetState(eeprom->i2c) == 2 )
    {
        // __HAL_I2C_CLEAR_FLAG(eeprom->i2c,I2C_FLAG_AF); //  清除非应答状态
        eeprom->i2c->State = HAL_I2C_STATE_READY;
        // i2c_clear_state(eeprom->i2c);
        eeprom->mem_addr--;
        eeprom->send_buf--;
        eeprom->size++;
    }
    if (eeprom->size == 0)
    {
        eeprom->send_buf = NULL;
        return 0;
    }

    // 单个字节写入 ?? 为什么指向的地址内容发送变化了,静态声明
    // LOG(  " send  buf  : %02x    %d", *eeprom->send_buf, eeprom->send_buf);
    HAL_I2C_Mem_Write_IT(eeprom->i2c, eeprom->dev_addr, eeprom->mem_addr, eeprom->mem_addr_type, eeprom->send_buf, 1 );
    // i2c_write_memory(eeprom->i2c,eeprom->dev_addr+eeprom->page_addr,eeprom->mem_addr,eeprom->mem_addr_size,eeprom->send_buf,1);
    // eeprom->time_base = __get_tick_milliseconds();
    eeprom->time_base = osKernelGetTickCount();
    eeprom->mem_addr++;
    eeprom->send_buf++;
    eeprom->size--;
    return 0;
}

void Eeprom_send_callback(eeprom_t *eeprom)
{
    Eeprom_send(eeprom);
}

uint8_t Eeprom_get_state(eeprom_t *eeprom)
{
    if (eeprom->send_buf != NULL)
    {
        return 1;
    }
    if ( HAL_I2C_GetState(eeprom->i2c) == HAL_I2C_STATE_READY )
    {
        return 0;
    };
    return 2;
}