#include "drv_bq27z561.h"
#include "battery_interface.h"
#include <drv_i2c.h>
#include <i2c.h>


/**
 * @brief 初始化bq27z561驱动
 * 
 * @return rt_err_t 返回初始化状态，RT_EOK 表示成功，其他值表示失败
*/
typedef struct {
    bool is_initlized;                      /**< 是否初始化 */
    struct rt_i2c_bus_device *device;       /**< i2c设备 */
} bq27z561_drv_t;

static bq27z561_drv_t g_bq27z561_drv;

/**
 * @brief 从bq27z561寄存器读取16位无符号整数
 * 
 * @param drv 指向bq27z561驱动结构体的指针
 * @param reg 要读取的寄存器地址
 * @param value 指向存储读取值的变量的指针
 * @return rt_err_t 返回读取状态，RT_EOK 表示成功，其他值表示失败   
 */
static rt_err_t bq27z561_read_u16(bq27z561_drv_t *drv, uint8_t reg, uint16_t *value)
{
    uint8_t buf[2] = {0};
    rt_size_t ret = rt_i2c_mem_read(drv->device, BQ27Z561_DRIVER_ADDR, reg, 1, buf, 2);
    // if (ret != 2) {
    //     rt_kprintf("func: %s, read u16 failed, ret = %d.\r\n", __func__, ret);
    //     return -RT_ERROR;
    // }
    *value = ((uint16_t)buf[1] << 8) | buf[0];

    return RT_EOK;
}

/**
 * @brief 初始化bq27z561驱动
 *
 * @return rt_err_t 返回初始化状态，RT_EOK 表示成功，其他值表示失败
 */
static rt_err_t bq27z561_drv_init(void)
{
    bq27z561_drv_t *drv = &g_bq27z561_drv;

    if(drv->is_initlized) {
        rt_kprintf("func: %s, bq27z561 driver is already initialized.\r\n", __func__);
        return RT_EOK;
    }

    drv->device = rt_i2c_bus_device_find(BQ27Z561_DRV_I2C_BUS_NAME);
    if(drv->device == NULL) {
        rt_kprintf("func: %s, can not found i2c bus %s.\r\n", __func__, BQ27Z561_DRV_I2C_BUS_NAME);
        return -RT_ERROR;
    }

    rt_err_t err = rt_device_open((rt_device_t)drv->device, RT_DEVICE_FLAG_RDWR);
    if (err != RT_EOK) {
        rt_kprintf("func: %s, open i2c bus %s failed.\r\n", __func__, BQ27Z561_DRV_I2C_BUS_NAME);
        return err;
    }

    struct rt_i2c_configuration i2c_cfg = {
        .mode = 0,
        .addr = 0,
        .timeout = 500,
        .max_hz = 400000,
    };
    err = rt_i2c_configure(drv->device, &i2c_cfg);
    if (err != RT_EOK) {
        rt_kprintf("func: %s, config i2c bus %s failed.\r\n", __func__, BQ27Z561_DRV_I2C_BUS_NAME);
        rt_device_close((rt_device_t)drv->device);
        return err;
    }

    drv->is_initlized = RT_TRUE;

    rt_kprintf("func: %s, i2c bus %s init success.\r\n", __func__, BQ27Z561_DRV_I2C_BUS_NAME);

    return RT_EOK;
}

/**
 * @brief 反初始化bq27z561驱动
 * @details 该函数关闭i2c设备，释放相关资源。
 * @return rt_err_t 返回反初始化状态，RT_EOK 表示成功，其他值表示失败
 */
static rt_err_t bq27z561_drv_deinit(void)
{
    bq27z561_drv_t *drv = &g_bq27z561_drv;

    if (drv->device) {
        rt_device_close((rt_device_t)drv->device);
    }
    drv->is_initlized = RT_FALSE;
    drv->device = NULL;

    return RT_EOK;
}

/**
 * @brief: 从bq27z561读取数据
 * @param: raw_data 读取到的数据存储地址
 * @return: rt_err_t 读取结果
*/  
static rt_err_t bq27z561_drv_read(battery_drv_raw_data_t *raw_data)
{
    bq27z561_drv_t *drv = &g_bq27z561_drv;

    if(!drv->is_initlized) {
        rt_kprintf("func: %s, bq27z561 driver is not initialized.\r\n", __func__);
        return -RT_ERROR;
    }

    uint16_t value = 0;

    if (bq27z561_read_u16(drv, BQ27Z561_VOLTAGE_REG, &value) != RT_EOK) {
        return -RT_ERROR;
    }
    raw_data->voltage = value;

    if (bq27z561_read_u16(drv, BQ27Z561_CURRENT_REG, &value) != RT_EOK) {
        return -RT_ERROR;
    }
    raw_data->current = (int16_t)value;

    if (bq27z561_read_u16(drv, BQ27Z561_TEMPERATURE_REG, &value) != RT_EOK) {
        return -RT_ERROR;
    }
    raw_data->temperature = (int16_t)value;

    if (bq27z561_read_u16(drv, BQ27Z561_STATUS_REG, &value) != RT_EOK) {
        return -RT_ERROR;
    }
    raw_data->status = value;

    if (bq27z561_read_u16(drv, BQ27Z561_SOC_REG, &value) != RT_EOK) {
        return -RT_ERROR;
    }
    raw_data->soc = value;

    if (bq27z561_read_u16(drv, BQ27Z561_REMAINING_CAPACITY_REG, &value) != RT_EOK) {
        return -RT_ERROR;
    }
    raw_data->remaining_capacity = value;

    if (bq27z561_read_u16(drv, BQ27Z561_FULL_CHARGE_CAPACITY_REG, &value) != RT_EOK) {
        return -RT_ERROR;
    }
    raw_data->full_charge_capacity = value;

    
    rt_kprintf("func: %s, voltage: %d, current: %d, temperature: %d, status: %d, soc: %d, remaining: %d, full: %d.\r\n", __func__, raw_data->voltage, raw_data->current, raw_data->temperature, raw_data->status, raw_data->soc, raw_data->remaining_capacity, raw_data->full_charge_capacity);

    return RT_EOK;
}

const battery_drv_ops_t g_bq27z561_drv_ops = {
    .name = "bq27z561",
    .init = bq27z561_drv_init,
    .read = bq27z561_drv_read,
    .ctrl = NULL,
    .deinit = bq27z561_drv_deinit,
};

/*
 * @brief 获取bq27z561驱动操作函数指针
 * @details 该函数返回bq27z561驱动的操作函数指针，用于调用驱动的初始化、读取、控制和反初始化函数。
 * @return const battery_drv_ops_t* 返回bq27z561驱动的操作函数指针  
*/
const battery_drv_ops_t *battery_drv_get_ops(void) {
    return &g_bq27z561_drv_ops;
}



