// Twi interface and macros/defines defined by you. // TWI接口与宏定义由上层提供
#include "CommonDefinesAndMacros.h" // 公共宏与工具头文件

/*
 * Note:    This was originally used with FreeRTOS so delays were doe through vTaskDelay.  // 原实现延时说明
 *          These lines are commented out but replace with your own delay() call. // 需要替换为平台延时
 *          原实现使用RTOS延时，这里需替换为平台自己的延时函数。 // 中文补充说明
*/ // 注释块结束

#include "FuelGauge.h" // 燃料计接口声明
#include "GoldenImage.h" // Golden Image配置脚本


/**
 *  Defines // 宏定义说明
 *  设备地址、寄存器地址与配置常量 // 地址与配置常量
 */ // 宏定义注释结束
#define FUEL_GAUGE_I2C_ADDRESS              0x55 // 0xAA is the 8-bit address // 设备I2C地址
#define FUEL_GAUGE_ROM_I2C_ADDRESS          0x0B // 0x16 is the 8-bit address // ROM模式I2C地址
#define FUEL_GAUGE_TWI_SPEED                TWI_100KHZ // 默认总线速率

#define FUEL_GAUGE_REG_CONTROL_STATUS       0x00 // 控制状态寄存器
#define FUEL_GAUGE_REG_VOLT                 0x08 // 电压寄存器
#define FUEL_GAUGE_REG_BATTERY_STATUS       0x0A // 电池状态寄存器
#define FUEL_GAUGE_REG_CURRENT              0x0C // 电流寄存器
#define FUEL_GAUGE_REG_REMAINING_CAP        0x10 // 剩余容量寄存器
#define FUEL_GAUGE_REG_FULL_CAP             0x12 // 满充容量寄存器
#define FUEL_GAUGE_REG_RELATIVE_SOC         0x2C // 相对SOC寄存器
#define FUEL_GAUGE_REG_RELATIVE_SOH         0x2E // 相对SOH寄存器
#define FUEL_GAUGE_REG_DESIGN_CAP           0x3C // 设计容量寄存器
#define FUEL_GAUGE_REG_ALT_MNFG_ACCESS      0x3E // 制造商访问寄存器

#define FUEL_GAUGE_REG_MAC_DATA_SUM         0x60 // MAC校验寄存器
#define FUEL_GAUGE_REG_VOLT_HI_SET_TH       0x62 // 高压告警设置阈值
#define FUEL_GAUGE_REG_VOLT_HI_CLR_TH       0x64 // 高压告警清除阈值
#define FUEL_GAUGE_REG_VOLT_LO_SET_TH       0x66 // 低压告警设置阈值
#define FUEL_GAUGE_REG_VOLT_LO_CLR_TH       0x68 // 低压告警清除阈值
#define FUEL_GAUGE_REG_TEMP_HI_SET_TH       0x6A // 高温告警设置阈值
#define FUEL_GAUGE_REG_TEMP_HI_CLR_TH       0x6B // 高温告警清除阈值
#define FUEL_GAUGE_REG_TEMP_LO_SET_TH       0x6C // 低温告警设置阈值
#define FUEL_GAUGE_REG_TEMP_LO_CLR_TH       0x6D // 低温告警清除阈值

#define FUEL_GAUGE_DF_POWER_CONFIG          0x4643 // DF电源配置值
#define FUEL_GAUGE_IT_ENABLED_BIT           3 // IT使能位
#define FUEL_GAUGE_LF_ENABLED_BIT           5 // LF使能位

#define NUMBER_FUEL_GAUGE_SETUP_REGISTERS   ARRAY_COUNT(registerSetup) // 配置表数量
#define FUEL_GAUGE_ENABLE_DELAY             1900 // 使能等待时间
#define FUEL_GAUGE_I2C_DELAY                1 // I2C延时


/**
 *  Local data // 本地数据说明
 *  用于解析golden image与安全访问的本地结构/枚举 // 本地结构体与枚举
 */ // 本地数据注释结束
typedef struct { // 配置块结构体
    const uint8_t *data; // 数据指针
    const uint16_t startAddress; // 起始地址
    const uint8_t size; // 数据长度
} Block; // 配置块结构体结束

typedef enum { // 安全密钥类型
    UNSEAL_KEY, // 解封密钥
    FULL_ACCESS_KEY, // 完全访问密钥
} FuelGaugeSecurityKey; // 安全密钥类型结束

// keys：解封与完全访问的密钥 // 密钥常量说明
static const uint8_t unsealKey [] = {0x04, 0x14, 0x36, 0x72}; // 解封密钥
static const uint8_t fullAccessKey [] = {0xff, 0xff, 0xff, 0xff}; // 完全访问密钥

// status commands (in little-endian format)：状态读取命令 // 状态命令说明
static const uint8_t chemIdCmd [] = {0x06, 0x00}; // 化学ID读取命令
static const uint8_t operationStatusCommand [] = {0x54, 0x00}; // 运行状态命令
static const uint8_t chargingStatusCommand [] = {0x55, 0x00}; // 充电状态命令
static const uint8_t gaugingStatusCommand [] = {0x56, 0x00}; // 计量状态命令
static const uint8_t manufacturingStatusCommand [] = {0x57, 0x00}; // 生产状态命令
static const uint8_t updateStatusAddress [] = {0x8c, 0x41}; // 更新状态地址
// setup commands (in little-endian format)：配置命令 // 配置命令说明
static const uint8_t enableImpedanceTrackingCommand [] = {0x21, 0x00}; // 使能IT命令
static const uint8_t disableImpedanceTrackingCommand [] = {0x21, 0x00}; // 禁用IT命令
static const uint8_t lifetimeTrackingCommand [] = {0x23, 0x00}; // 使能寿命跟踪命令
static const uint8_t resetCommand [] = {0x41, 0x00}; // 复位命令
static const uint8_t sealCommand [] = {0x30, 0x00}; // 封装命令
static const uint8_t resetLifetimeCmd [] = {0x28, 0x00}; // 寿命历史复位命令
static const uint8_t securityKeysCmd [] = {0x35, 0x00}; // 读取密钥命令
static const uint8_t exitRomCmd [] = {0x08}; // 退出ROM命令
//static const uint8_t enterRomCmd [] = {0x00, 0x0f}; // be careful! // 进入ROM命令（慎用）

static TwiInterface *Twi = NULL;     // I2C/TWI接口实例，由上层注入 // 全局TWI句柄

/**
 *  Local function prototypes // 本地函数原型
 *  内部读写与状态解析辅助函数 // 内部辅助函数说明
 */ // 原型注释结束
static inline bool PrimedReadOperation(const uint8_t registerAddress, // 预置读操作
                                       const uint8_t *cmd, // 命令指针
                                       const uint8_t sizeOfCmd, // 命令长度
                                       uint8_t *data, // 输出数据缓冲
                                       const uint8_t sizeOfData); // 输出长度
static inline bool ReadFlashBlock(const uint8_t fgAddress, // 读取Flash块
                                  const uint8_t registerAddress, // 寄存器地址
                                  uint8_t *value, // 数据缓冲
                                  const uint8_t size); // 数据长度
static inline bool WriteFlashBlock(const uint8_t registerAddress, // 写入Flash块
                                   const uint8_t *value, // 数据指针
                                   const uint8_t size); // 数据长度
static inline bool WriteFlashBlockSafe(const uint8_t fgAddress, // 安全写入Flash块
                                       const uint8_t registerAddress, // 寄存器地址
                                       const uint8_t *value, // 数据指针
                                       const uint8_t size); // 数据长度
static inline bool GetCommon(const uint8_t registerAddress, // 通用寄存器读取
                             uint16_t *value); // 输出值
static inline bool IsImpedanceTrackingEnabled(void); // 查询IT使能状态
static inline bool IsLifetimeTrackingEnabled(void); // 查询寿命跟踪状态
static inline void GetKey(FuelGaugeSecurityKey desiredKey, uint8_t *key); // 获取密钥


void FuelGaugeInitTwi(TwiInterface *twi) // 初始化TWI接口
{ // 函数开始
    configASSERT(twi != NULL); // 参数校验

    Twi = twi; // 保存接口指针
} // 函数结束

/**
* \brief Gets control status from the BQ27Z561. // 读取控制状态
*/ // 注释结束
bool FuelGaugeGetControlStatus(uint16_t *controlStatus) // 获取控制状态
{ // 函数开始
    return GetCommon(FUEL_GAUGE_REG_CONTROL_STATUS, controlStatus); // 调用通用读
} // 函数结束

/**
* \brief Gets voltage from the BQ27Z561. // 读取电压
*/ // 注释结束
bool FuelGaugeGetVoltage(uint16_t *voltage) // 获取电压
{ // 函数开始
    return GetCommon(FUEL_GAUGE_REG_VOLT, voltage); // 调用通用读
} // 函数结束

/**
* \brief Gets status of battery from the BQ27Z561. // 读取电池状态
*/ // 注释结束
bool FuelGaugeGetBatteryStatus(uint16_t *status) // 获取电池状态
{ // 函数开始
    return GetCommon(FUEL_GAUGE_REG_BATTERY_STATUS, status); // 调用通用读
} // 函数结束

/**
* \brief Gets manufacturing status of battery from the BQ27Z561. // 读取制造状态
*/ // 注释结束
bool FuelGaugeGetManufacturingStatus(uint16_t *status) // 获取制造状态
{ // 函数开始
    uint8_t values [] = {0xff, 0xff, 0xff, 0xff}; // 本地缓存

    bool result = PrimedReadOperation(FUEL_GAUGE_REG_ALT_MNFG_ACCESS, // 预置读
                                      manufacturingStatusCommand, // 制造状态命令
                                      sizeof(manufacturingStatusCommand), // 命令长度
                                      values, // 输出缓冲
                                      sizeof(values)); // 输出长度

    (*status) = ((values[3] << 8) | values[2]); // 拼接结果

    return result; // 返回读结果
} // 函数结束

/**
* \brief Gets operation status for the BQ27Z561. // 读取运行状态
*/ // 注释结束
bool FuelGaugeGetOperationStatus(uint32_t *opStatus) // 获取运行状态
{ // 函数开始
    uint8_t values [] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; // 本地缓存

    bool result = PrimedReadOperation(FUEL_GAUGE_REG_ALT_MNFG_ACCESS, // 预置读
                                      operationStatusCommand, // 运行状态命令
                                      sizeof(operationStatusCommand), // 命令长度
                                      values, // 输出缓冲
                                      sizeof(values)); // 输出长度

    (*opStatus) = ((values[3] << 24) | (values[2] << 16) | (values[5] << 8) | values[4]); // 拼接结果

    return result; // 返回读结果
} // 函数结束

/**
* \brief Gets gauging status for the BQ27Z561. // 读取计量状态
*/ // 注释结束
bool FuelGaugeGetGaugingStatus(uint32_t *gaugingStatus) // 获取计量状态
{ // 函数开始
    uint8_t values [] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; // 本地缓存

    bool result = PrimedReadOperation(FUEL_GAUGE_REG_ALT_MNFG_ACCESS, // 预置读
                                      gaugingStatusCommand, // 计量状态命令
                                      sizeof(gaugingStatusCommand), // 命令长度
                                      values, // 输出缓冲
                                      sizeof(values)); // 输出长度

    (*gaugingStatus) = ((values[3] << 24) | (values[2] << 16) | (values[5] << 8) | values[4]); // 拼接结果

    return result; // 返回读结果
} // 函数结束

/**
* \brief Gets charging status for the BQ27Z561. // 读取充电状态
*/ // 注释结束
bool FuelGaugeGetChargingStatus(uint32_t *chargingStatus) // 获取充电状态
{ // 函数开始
    uint8_t values [] = {0xff, 0xff, 0xff, 0xff, 0xff}; // 本地缓存

    bool result = PrimedReadOperation(FUEL_GAUGE_REG_ALT_MNFG_ACCESS, // 预置读
                                      chargingStatusCommand, // 充电状态命令
                                      sizeof(chargingStatusCommand), // 命令长度
                                      values, // 输出缓冲
                                      sizeof(values)); // 输出长度

    // Returns three bytes. Upper byte is Temp range, lower 2 bytes are charging status flags. // 返回值说明
    (*chargingStatus) = 0x0; // 初始化输出
    (*chargingStatus) = ((values[2] << 16) | (values[4] << 8) | values[3]); // 拼接结果

    return result; // 返回读结果
} // 函数结束

/**
* \brief Gets Chem ID of battery programmed on the BQ27Z561. // 读取化学ID
*/ // 注释结束
bool FuelGaugeGetChemId(uint16_t *chemId) // 获取化学ID
{ // 函数开始
    uint8_t values [] = {0xff, 0xff, 0xff, 0xff}; // 本地缓存

    bool result = PrimedReadOperation(FUEL_GAUGE_REG_ALT_MNFG_ACCESS, // 预置读
                                      chemIdCmd, // 化学ID命令
                                      sizeof(chemIdCmd), // 命令长度
                                      values, // 输出缓冲
                                      sizeof(values)); // 输出长度

    (*chemId) = ((values[3] << 8) | values[2]); // 拼接结果

    return result; // 返回读结果
} // 函数结束

bool FuelGaugeGetUpdateStatus(uint8_t *updateStatus) // 获取更新状态
{ // 函数开始
    uint8_t value [] = {0xff, 0xff, 0xff}; // 本地缓存

    bool result = PrimedReadOperation(FUEL_GAUGE_REG_ALT_MNFG_ACCESS, // 预置读
                                      updateStatusAddress, // 更新状态地址
                                      ARRAY_COUNT(updateStatusAddress), // 地址长度
                                      value, // 输出缓冲
                                      sizeof(value)); // 输出长度

    (*updateStatus) = value[2]; // 取出状态字节

    return result; // 返回读结果
} // 函数结束

/**
* \brief Gets current from the BQ27Z561. // 读取电流
*/ // 注释结束
bool FuelGaugeGetCurrent(int16_t *current) // 获取电流
{ // 函数开始
    return GetCommon(FUEL_GAUGE_REG_CURRENT, (uint16_t *) current); // 调用通用读
} // 函数结束

/**
* \brief Gets remaining battery capacity from the BQ27Z561. // 读取剩余容量
*/ // 注释结束
bool FuelGaugeGetRemainingCapacity(uint16_t *capacity) // 获取剩余容量
{ // 函数开始
    return GetCommon(FUEL_GAUGE_REG_REMAINING_CAP, capacity); // 调用通用读
} // 函数结束

/**
* \brief Gets predicted fully-charged battery capacity from the BQ27Z561. // 读取满充容量
*/ // 注释结束
bool FuelGaugeGetFullChargeCapacity(uint16_t *capacity) // 获取满充容量
{ // 函数开始
    return GetCommon(FUEL_GAUGE_REG_FULL_CAP, capacity); // 调用通用读
} // 函数结束

/**
* \brief Gets relative state-of-charge (SoC) as % from the BQ27Z561. // 读取相对SOC
*/ // 注释结束
bool FuelGaugeGetRelativeSoc(uint16_t *soc) // 获取相对SOC
{ // 函数开始
    return GetCommon(FUEL_GAUGE_REG_RELATIVE_SOC, soc); // 调用通用读
} // 函数结束

/**
* \brief Gets the state-of-health (SoH) information of the battery in // 读取SOH
*   percentage of Design Capacity from the BQ27Z561. // 以设计容量百分比表示
*/ // 注释结束
bool FuelGaugeGetSoh(uint16_t *soh) // 获取SOH
{ // 函数开始
    return GetCommon(FUEL_GAUGE_REG_RELATIVE_SOH, soh); // 调用通用读
} // 函数结束

/**
* \brief Gets design capacity for the BQ27Z561. // 读取设计容量
*/ // 注释结束
bool FuelGaugeGetCapacity(uint16_t *capacity) // 获取设计容量
{ // 函数开始
    return GetCommon(FUEL_GAUGE_REG_DESIGN_CAP, capacity); // 调用通用读
} // 函数结束

/**
* \brief Enable the Impedance Tracking algorithm on the BQ27Z561. // 使能阻抗跟踪
*/ // 注释结束
bool FuelGaugeEnableImpedanceTracking(void) // 使能IT
{ // 函数开始
    if (IsImpedanceTrackingEnabled() == true) // IT already enabled // 已使能则直接返回
        return true; // 已使能

    WriteFlashBlockSafe(FUEL_GAUGE_I2C_ADDRESS, // 写入地址
                        FUEL_GAUGE_REG_ALT_MNFG_ACCESS, // 制造商访问寄存器
                        enableImpedanceTrackingCommand, // 使能命令
                        sizeof(enableImpedanceTrackingCommand)); // 命令长度

    return IsImpedanceTrackingEnabled(); // 再次确认
} // 函数结束

/**
* \brief Disable the Impedance Tracking algorithm on the BQ27Z561. // 禁用阻抗跟踪
*/ // 注释结束
bool FuelGaugeDisableImpedanceTracking(void) // 禁用IT
{ // 函数开始
    if (IsImpedanceTrackingEnabled() == true) { // 条件判断
        WriteFlashBlockSafe(FUEL_GAUGE_I2C_ADDRESS, // 写入地址
                            FUEL_GAUGE_REG_ALT_MNFG_ACCESS, // 制造商访问寄存器
                            disableImpedanceTrackingCommand, // 禁用命令
                            sizeof(disableImpedanceTrackingCommand)); // 命令长度
    } // 条件结束

    return IsImpedanceTrackingEnabled(); // 返回当前状态
} // 函数结束

/**
* \brief Enable the Lifetime Tracking algorithm on the BQ27Z561. // 使能寿命跟踪
*/ // 注释结束
bool FuelGaugeEnableLifetimeTracking(void) // 使能LF
{ // 函数开始
    if (IsLifetimeTrackingEnabled() == true) // Lifetime already enabled // 已使能则返回
        return true; // 直接返回

    WriteFlashBlockSafe(FUEL_GAUGE_I2C_ADDRESS, // 写入地址
                        FUEL_GAUGE_REG_ALT_MNFG_ACCESS, // 制造商访问寄存器
                        lifetimeTrackingCommand, // 使能命令
                        sizeof(lifetimeTrackingCommand)); // 命令长度

    return IsLifetimeTrackingEnabled(); // 再次确认
} // 函数结束

/**
* \brief Disable the Lifetime Tracking algorithm on the BQ27Z561. // 禁用寿命跟踪
*/ // 注释结束
bool FuelGaugeDisableLifetimeTracking(void) // 禁用LF
{ // 函数开始
    if (IsImpedanceTrackingEnabled() == true) { // 条件判断
        WriteFlashBlockSafe(FUEL_GAUGE_I2C_ADDRESS, // 写入地址
                            FUEL_GAUGE_REG_ALT_MNFG_ACCESS, // 制造商访问寄存器
                            lifetimeTrackingCommand, // 禁用命令
                            sizeof(lifetimeTrackingCommand)); // 命令长度
    } // 条件结束

    return IsLifetimeTrackingEnabled(); // 返回当前状态
} // 函数结束

/**
* \brief Resets the BQ27Z561. // 复位芯片
*/ // 注释结束
bool FuelGaugeReset(void) // 复位函数
{ // 函数开始
    bool result = WriteFlashBlockSafe(FUEL_GAUGE_I2C_ADDRESS, // 写入地址
                                      FUEL_GAUGE_REG_ALT_MNFG_ACCESS, // 制造商访问寄存器
                                      resetCommand, // 复位命令
                                      sizeof(resetCommand)); // 命令长度

    return result; // 返回写入结果
} // 函数结束

/**
* \brief Unseals the BQ27Z561. // 解封芯片
*/ // 注释结束
bool FuelGaugeUnseal(void) // 解封函数
{ // 函数开始
    configASSERT(Twi != NULL); // 断言接口已注入

    uint8_t keyFirstWord[] = {unsealKey[0], unsealKey[1]}; // 第一字
    uint8_t keySecondWord[] = {unsealKey[2], unsealKey[3]}; // 第二字

    bool result = false; // 返回值初始化

    if (Twi->open(FUEL_GAUGE_TWI_SPEED) == true) { // 打开总线
        result = WriteFlashBlock(FUEL_GAUGE_REG_ALT_MNFG_ACCESS, // 写入寄存器
                                 keyFirstWord, // 写入第一字
                                 ARRAY_COUNT(keyFirstWord)); // 长度

        result &= WriteFlashBlock(FUEL_GAUGE_REG_ALT_MNFG_ACCESS, // 写入寄存器
                                  keySecondWord, // 写入第二字
                                  ARRAY_COUNT(keySecondWord)); // 长度

        Twi->close(); // 关闭总线
    } // 条件结束

    return result; // 返回结果
} // 函数结束

/**
* \brief Gives full access to the BQ27Z561. // 完全访问
*/ // 注释结束
bool FuelGaugeFullAccess(void) // 完全访问函数
{ // 函数开始
    configASSERT(Twi != NULL); // 断言接口已注入
    
    uint8_t keyFirstWord[] = {fullAccessKey[0], fullAccessKey[1]}; // 第一字
    uint8_t keySecondWord[] = {fullAccessKey[2], fullAccessKey[3]}; // 第二字

    bool result = false; // 返回值初始化

    if (Twi->open(FUEL_GAUGE_TWI_SPEED) == true) { // 打开总线
        result = WriteFlashBlock(FUEL_GAUGE_REG_ALT_MNFG_ACCESS, // 写入寄存器
                                 keyFirstWord, // 写入第一字
                                 ARRAY_COUNT(keyFirstWord)); // 长度

        result &= WriteFlashBlock(FUEL_GAUGE_REG_ALT_MNFG_ACCESS, // 写入寄存器
                                  keySecondWord, // 写入第二字
                                  ARRAY_COUNT(keySecondWord)); // 长度

        Twi->close(); // 关闭总线
    } // 条件结束

    return result; // 返回结果
} // 函数结束

/**
* \brief Seals the BQ27Z561. // 封装芯片
*/ // 注释结束
bool FuelGaugeSeal(void) // 封装函数
{ // 函数开始
    return WriteFlashBlockSafe(FUEL_GAUGE_I2C_ADDRESS, // 写入地址
                               FUEL_GAUGE_REG_ALT_MNFG_ACCESS, // 制造商访问寄存器
                               sealCommand, // 封装命令
                               sizeof(sealCommand)); // 命令长度
} // 函数结束

/**
* \brief Resets lifetime history of battery BQ27Z561. // 清除寿命历史
*/ // 注释结束
bool FuelGaugeResetLifetimeHistory(void) // 清除寿命历史
{ // 函数开始
    return WriteFlashBlockSafe(FUEL_GAUGE_I2C_ADDRESS, // 写入地址
                               FUEL_GAUGE_REG_ALT_MNFG_ACCESS, // 制造商访问寄存器
                               resetLifetimeCmd, // 清除命令
                               sizeof(resetLifetimeCmd)); // 命令长度
} // 函数结束

/**
* \brief Send return-to-firmware command if BQ27Z561 is in ROM mode. // 退出ROM模式
*/ // 注释结束
bool FuelGaugeExitRomMode(void) // 退出ROM模式
{ // 函数开始
    configASSERT(Twi != NULL); // 断言接口已注入

    bool result = false; // 返回值初始化

    if (Twi->open(TWI_400KHZ) == true) { // 打开高速总线
        result = Twi->write(FUEL_GAUGE_ROM_I2C_ADDRESS, // ROM地址
                              (uint8_t *)FUEL_GAUGE_REG_ALT_MNFG_ACCESS, // 寄存器地址
                              sizeof(uint8_t), // 地址长度
                              exitRomCmd, // 退出命令
                              sizeof(exitRomCmd)); // 命令长度

        Twi->close(); // 关闭总线
    } // 条件结束

    return result; // 返回结果
} // 函数结束

/**
* \brief Execute a flash stream file onto BQ27Z561. // 执行golden image脚本
*/ // 注释结束
FuelGaugeConfigError FuelGaugeExecuteGoldenImage(void) // 执行配置脚本
{ // 函数开始
    configASSERT(Twi != NULL); // 断言接口已注入

    uint16_t length = strlen(goldenImage); // 脚本总长度
    char buf[16]; // 临时缓冲
    uint16_t index = 0; // 当前位置

    while (index < length) { // 遍历脚本
        switch (goldenImage[index]) { // 解析指令类型
            // writing/reading fuel gauge：写入/校验配置块 // 写入或校验指令
            case 'W': // 写入指令
            case 'C': { // 校验指令
                bool writeCmd = (goldenImage[index++] == 'W'); // 判断是否写入

                if (goldenImage[index++] != ':') // 校验格式
                    return ERROR_COLON; // 返回格式错误

                uint16_t byteNum = 1; // 字节计数
                uint8_t data[34]; // 数据缓存
                uint8_t fgAddress = 0; // 设备地址
                unsigned char fgRegister = 0; // 寄存器地址

                while ((length - index > 2) && (byteNum < sizeof(data) + 3) && (goldenImage[index] != '\n')) { // 解析一行
                    // copy two values from file // 复制两个字符
                    buf[0] = goldenImage[index++]; // 高半字节
                    buf[1] = goldenImage[index++]; // 低半字节
                    // set zero-terminated // 结尾补零
                    buf[2] = 0; // 字符串结尾
                    // convert string to hex // 转换为数值
                    char *pError; // 转换错误指针
                    uint8_t convertedData = strtoul(buf, &pError, 16); // 解析十六进制

                    // check if conversion was successful // 检查转换结果
                    if (*pError) // 转换失败
                        return ERROR_CONV; // 返回转换错误

                    // handle address // 处理地址
                    if (byteNum == 1) // 地址字段
                        fgAddress = convertedData; // 保存设备地址

                    // set register // 设置寄存器
                    if (byteNum == 2) // 寄存器字段
                        fgRegister = convertedData; // 保存寄存器地址

                    // construct data from file // 组装数据
                    if (byteNum > 2) // 数据字段
                        data[byteNum - 3] = convertedData; // 保存数据

                    byteNum++; // 计数递增
                } // 行解析结束

                if (byteNum < 4) // 长度不足
                    return ERROR_COUNT; // 返回长度错误

                uint8_t dataLength = byteNum - 3; // 有效数据长度

                if (writeCmd) { // 写入模式
                    // the data in the golden image file is in little endian format // 小端序说明
                    WriteFlashBlockSafe((fgAddress >> 1), fgRegister, data, dataLength); // 写入数据
                } else { // 校验模式
                    uint8_t dataFromGauge[dataLength]; // 读取回来的数据

                    if (Twi->open(FUEL_GAUGE_TWI_SPEED) == true) { // 打开总线
                        ReadFlashBlock((fgAddress >> 1), fgRegister, dataFromGauge, dataLength); // 读取数据
                        Twi->close(); // 关闭总线
                    } // 条件结束

                    if (memcmp(data, dataFromGauge, dataLength)) // 比较数据
                        return ERROR_MEMCMP; // 返回不一致错误
                } // 写入/校验结束

                break; // 结束当前指令
            } // 指令块结束

            // handle delay：延时指令 // 延时指令说明
            case 'X': { // 延时指令
                index++; // 跳过指令字符

                if (goldenImage[index] != ':') // 校验格式
                    return ERROR_COLON; // 返回格式错误

                index++; // 跳过冒号
                uint8_t n = 0; // 延时字符串长度

                while ((index < length) && (goldenImage[index] != '\n') && (n < sizeof(buf) - 1)) // 读取延时值
                    buf[n++] = goldenImage[index++]; // 复制字符

                // set zero-terminated // 结尾补零
                buf[n] = 0; // 字符串结尾
                n = atoi(buf); // 转为数字
                //vTaskDelay(n); // 平台延时函数

                break; // 结束延时指令
            } // 延时块结束

            default: // 未知指令
                return ERROR_DEFAULT; // 返回默认错误
        } // switch结束

        while ((index < length) && (goldenImage[index] != '\n')) // 跳到行尾
            index++; //skip to next line // 跳过本行

        if (index < length) // 若未到末尾
            index++; // 跳过换行
    } // 脚本遍历结束

    return ERROR_NONE; // 返回成功
} // 函数结束

/***********************************************************************
   Static functions. // 静态函数区
***********************************************************************/ // 分隔注释结束
static inline bool GetCommon(const uint8_t registerAddress, // 通用寄存器读取
                             uint16_t *value) // 输出值
{ // 函数开始
    configASSERT(Twi != NULL); // 断言接口已注入

    bool result = false; // 返回值初始化

    if (Twi->open(FUEL_GAUGE_TWI_SPEED) == true) { // 打开总线
        result = Twi->read(FUEL_GAUGE_I2C_ADDRESS, &registerAddress, sizeof(uint8_t), value, // 读取寄存器
                             sizeof(uint16_t)); // 读取长度
        Twi->close(); // 关闭总线
        // minimum 66-us delay required before next I2C transaction // 最小间隔说明
        //vTaskDelay(FUEL_GAUGE_I2C_DELAY); // 平台延时
    } // 条件结束

    return result; // 返回结果
} // 函数结束

    // We have the ability to read the keys, but I also hard-coded const declarations of both keys to simplify // 英文说明
    // 可读取密钥，但这里保留固定常量以简化流程 // 中文说明
static inline void GetKey(FuelGaugeSecurityKey desiredKey, uint8_t *key) // 读取密钥
{ // 函数开始
    uint8_t values [] = { // 密钥缓存
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff // 初始值
    }; // 数组结束

    PrimedReadOperation(FUEL_GAUGE_REG_ALT_MNFG_ACCESS, // 预置读寄存器
                        securityKeysCmd, // 密钥命令
                        sizeof(securityKeysCmd), // 命令长度
                        values, // 输出缓冲
                        sizeof(values)); // 输出长度

    if (desiredKey == UNSEAL_KEY) { // 解封密钥
        uint8_t unsealedKey [] = {values[2], values[3], values[4], values[5]}; // 解封密钥值
        memcpy(key, unsealedKey, sizeof(unsealedKey)); // 拷贝密钥
    } else if (desiredKey == FULL_ACCESS_KEY) { // 完全访问密钥
        uint8_t fullAccKey [] = {values[6], values[7], values[8], values[9]}; // 完全访问密钥值
        memcpy(key, fullAccKey, sizeof(fullAccKey)); // 拷贝密钥
    } // 条件结束
} // 函数结束

static inline bool PrimedReadOperation(const uint8_t registerAddress, // 预置读操作
                                       const uint8_t *cmd, // 命令指针
                                       const uint8_t sizeOfCmd, // 命令长度
                                       uint8_t *data, // 数据缓冲
                                       const uint8_t sizeOfData) // 数据长度
{ // 函数开始
    configASSERT(Twi != NULL); // 断言接口已注入

    bool result = false; // 返回值初始化

    if (Twi->open(FUEL_GAUGE_TWI_SPEED) == true) { // 打开总线
        // Configure pointer to flash location // 配置读取指针
        result = WriteFlashBlock(registerAddress, cmd, sizeOfCmd); // 写入命令
        // Read from desired flash location // 读取数据
        result &= ReadFlashBlock(FUEL_GAUGE_I2C_ADDRESS, registerAddress, data, sizeOfData); // 读取数据

        Twi->close(); // 关闭总线
    } // 条件结束

    return result; // 返回结果
} // 函数结束

static inline bool IsImpedanceTrackingEnabled(void) // 判断IT是否使能
{ // 函数开始
    uint16_t manfStatus; // 制造状态缓存
    FuelGaugeGetManufacturingStatus(&manfStatus); // 读取制造状态

    bool result = (BIT_IS_SET(manfStatus, FUEL_GAUGE_IT_ENABLED_BIT)); // 判断使能位

    return result; // 返回结果
} // 函数结束

static inline bool IsLifetimeTrackingEnabled(void) // 判断寿命跟踪是否使能
{ // 函数开始
    uint16_t manfStatus; // 制造状态缓存
    FuelGaugeGetManufacturingStatus(&manfStatus); // 读取制造状态

    bool result = (BIT_IS_SET(manfStatus, FUEL_GAUGE_LF_ENABLED_BIT)); // 判断使能位

    return result; // 返回结果
} // 函数结束

static inline bool ReadFlashBlock(const uint8_t fgAddress, // 读取Flash块
                                  const uint8_t registerAddress, // 寄存器地址
                                  uint8_t *value, // 数据缓冲
                                  const uint8_t size) // 数据长度
{ // 函数开始
    configASSERT(Twi != NULL); // 断言接口已注入

    bool result = Twi->read(fgAddress, // 设备地址
                            &registerAddress, // 寄存器地址
                            sizeof(uint8_t), // 地址长度
                            value, // 输出缓冲
                            size); // 数据长度

    // vTaskDelay(FUEL_GAUGE_I2C_DELAY); // minimum 66-us delay required before next I2C transaction // 延时说明

    return result; // 返回结果
} // 函数结束

static inline bool WriteFlashBlock(const uint8_t registerAddress, // 写入Flash块
                                   const uint8_t *value, // 数据指针
                                   const uint8_t size) // 数据长度
{ // 函数开始
    configASSERT(Twi != NULL); // 断言接口已注入

    bool result = Twi->write(FUEL_GAUGE_I2C_ADDRESS, // 设备地址
                             &registerAddress, // 寄存器地址
                             sizeof(uint8_t), // 地址长度
                             value, // 数据指针
                             size); // 数据长度

    //vTaskDelay(FUEL_GAUGE_I2C_DELAY); // minimum 66-us delay required before next I2C transaction // 延时说明

    return result; // 返回结果
} // 函数结束

static inline bool WriteFlashBlockSafe(const uint8_t fgAddress, // 安全写入Flash块
                                       const uint8_t registerAddress, // 寄存器地址
                                       const uint8_t *value, // 数据指针
                                       const uint8_t size) // 数据长度
{ // 函数开始
    configASSERT(Twi != NULL); // 断言接口已注入

    bool result = false; // 返回值初始化

    if (Twi->open(FUEL_GAUGE_TWI_SPEED) == true) { // 打开总线
        result = Twi->write(fgAddress, // 设备地址
                            &registerAddress, // 寄存器地址
                            sizeof(uint8_t), // 地址长度
                            value, // 数据指针
                            size); // 数据长度

        Twi->close(); // 关闭总线
    } // 条件结束

    //vTaskDelay(FUEL_GAUGE_I2C_DELAY); // minimum 66-us delay required before next I2C transaction // 延时说明

    return result; // 返回结果
} // 函数结束
