ZHCACL8A october 2022 – april 2023 LP8764-Q1 , TPS6594-Q1
更新第 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 页和第 4 页寄存器 CRC 有两个组成部分:包含持续和排除持续。如表 5-4 所示,包含持续 CRC 信息存储在第 0 页寄存器 0xF0 和 0xF1 中,排除持续存储在第 0 页寄存器 0xF2 和 0xF3 中。
寄存器 | 地址,第 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];
}
}