ZHCACL8A october   2022  – april 2023 LP8764-Q1 , TPS6594-Q1

 

  1.   1
  2.   摘要
  3.   商标
  4. 1引言
  5. 2硬件和 PMIC 设置
  6. 3配置概述
  7. 4指令
  8. 5特殊注意事项
    1. 5.1 更改串行控制接口
    2. 5.2 更新频率选择
    3. 5.3 PFSM
    4. 5.4 永久锁定 NVM
    5. 5.5 更新寄存器 CRC
  9. 6NVM 验证
  10. 7参考文献
  11.   A 由 NVM 支持的寄存器
  12.   B 属于寄存器 CRC 的非 NVM 寄存器
  13.   C 用户寄存器的 CRC,第 0 页和第 4 页
  14.   D I2C 串行接口示例
  15.   E 修订历史记录

更新寄存器 CRC

注: 只有在所编程的 NVM 中启用寄存器 CRC 时,才需要更新寄存器 CRC。已设置第 1 页寄存器 0x18 的位 6。

更新第 3 页和第 1 页寄存器 CRC 内容的过程使用 PMIC 中的 CRC 更新特性。运行 CRC 更新之前,请清除地址 0xF0 到 0xFB 中的寄存器 CRC 内容。设置第 0 页寄存器 0xEF 的位 1 后,将执行 CRC 更新。该位会自行清除。更新完成后,第 0 页地址 0xFB 的内容变为非零值。建议对寄存器 0xFB 执行这项从 0 变为非零值的检查以确认 CRC 完成,然后再尝试继续执行下一步。

PMIC CRC 更新特性计算第 0、1、3 和 4 页的 CRC。第 2 页是受保护的存储空间以及相关的 CRC,本文档未对此进行介绍。在大多数应用中,用户寄存器的计算(第 1 页和第 4 页的组合)不正确。第 0 页寄存器 0x82 的值与默认值不匹配,请参阅AppendixB,并且只能从串行接口读取寄存器中的 SPMI_LPM_EN 位和 FORCE_EN_DRV_LOW 位。

注: 如果第 0 页寄存器 0x82 的数据值 ENABLE_DRV_STAT 不是 0x08,则必须手动计算第 0 页和第 4 页的寄存器 CRC,并将结果写入 PMIC。

第 0 页和第 4 页寄存器 CRC 有两个组成部分:包含持续和排除持续。如表 5-4 所示,包含持续 CRC 信息存储在第 0 页寄存器 0xF0 和 0xF1 中,排除持续存储在第 0 页寄存器 0xF2 和 0xF3 中。

表 5-4 用户寄存器(第 0 页和第 4 页)寄存器 CRC 寄存器
寄存器 地址,第 0 页 Bit7-Bit0
CRC_1 0xF0 REGMAP_USER_INCLUDE_PERSIST_CRC16_LOW
CRC_2 0xF1 REGMAP_USER_INCLUDE_PERSIST_CRC16_HIGH
CRC_3 0xF2 REGMAP_USER_EXCLUDE_PERSIST_CRC16_LOW
CRC_4 0xF3 REGMAP_USER_EXCLUDE_PERSIST_CRC16_HIGH

以下代码片段中显示的 CRC 计算取自可扩展 PMIC GUI(请参阅参考文献 3)。AppendixC 作为寄存器信息的数组提供。与看门狗相关的信息将映射到适当的位置,如果不受 NVM 支持,寄存器将填充默认设置,如果未定义,则填充 0x00。


const CRC_POLYNOMIAL = 0x755b;
var calculate_register_crc = function(registers, regmap_json, include_persist, page) {
    crc = 0xffff;
    for (var address = 0; address < 0x100; address++) {
        var data;
        var json_address;
        if (address >= 0xf0 && page === 0) {
            // Watchdog registers is mapped from 0x0fX in array to 0x40X in register map
            // Offset by 1 since 0x0f0 is mapped to 0x401
            json_address = address + 0x310 + 1;
        } else {
            json_address = address + (page * 0x100);
        }
        if (registers[address] === undefined) {
            if (json_address in regmap_json) {
                // Non-NVM register uses reset value
                data = regmap_json[json_address].reset;
            } else {
                // Register does not exist, so reads 0s
                data = 0;
            }
        } else {
            // Regsiter is NVM-backed, use value from device
            data = registers[address];
        }
        var crc_mask = 0x00;
        if (json_address in regmap_json) {
            if (include_persist) {
                crc_mask = regmap_json[json_address].crc_mask_include_persist;
            } else {
                crc_mask = regmap_json[json_address].crc_mask_exclude_persist;
            }
        }
        data = data & crc_mask;
        crc = crc_d8(crc, data);
    }
    return crc;
};
// Calculate CRC based on look-up table
var crc_d8 = function(crc, data) {
    var table_index = data ^ ((crc & 0xff00) >> 8);
    crc = (crc << 8) ^ lookup_table[table_index];
    return crc & 0xffff;  
};
// Compute lookup-table used for CRC calculation
crc = 0x8000;
for (var i = 1; i < 256; i <<= 1) {
    if ((crc & 0x8000) !== 0) {
        crc = ((crc << 1) ^ CRC_POLYNOMIAL) & 0xffff;
    } else {
        crc = (crc << 1) & 0xffff;
    }
    for (var j = 0; j < i; j++) {
        lookup_table[i+j] = crc ^ lookup_table[j];
    }
}