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

 

  1.   Abstract
  2.   Trademarks
  3. 1Introduction
  4. 2Hardware and PMIC Setup
  5. 3Configuration Overview
  6. 4Instructions
  7. 5Special Considerations
    1. 5.1 Changing the Serial Control Interface
    2. 5.2 Updating the Frequency Selection
    3. 5.3 PFSM
    4. 5.4 Permanently Locking the NVM
    5. 5.5 Updating the Register CRC
  8. 6NVM Validation
  9. 7References
  10.   A Registers Backed by NVM
  11.   B Non-NVM Registers Which are Part of the Register CRC
  12.   C CRC for User Registers, Page 0 and Page 4
  13.   D Example With I2C Serial Interface
  14.   E Revision History

Updating the Register CRC

Note: The Register CRC update is only required if the Register CRC is enabled in the NVM being programmed. Bit 6, of register 0x18, of page 1 is set.

The process for updating the register CRC for the Page 3 and Page 1 contents uses the CRC update feature within the PMIC. Before running the CRC update, clear the register CRC contents in address 0xF0 through 0xFB. The CRC update is performed when bit 1 of register 0xEF in page 0 is set. This bit is self-clearing. Once the update is complete, the content of address 0xFB, page 0, becomes a non-zero value. This check of register 0xFB changing from a 0 to non-zero number is recommended to confirm that the CRC is complete before attempting move on to the next step.

The PMIC CRC update feature calculates the CRC for pages 0,1,3, and 4. Page 2 is protected memory space as well as the associated CRC and is not described in this document. In most applications the calculation for the user registers, the combination of pages 1 and 4, is incorrect. The value of register 0x82 on page 0 does not match the default value, see Appendix B, and the bits SPMI_LPM_EN and FORCE_EN_DRV_LOW, found in the register are read only from the serial interface.

Note: If the data value of Page 0 register 0x82, ENABLE_DRV_STAT, is not 0x08, then the register CRC for Page 0 and Page 4 must be computed manually and the results written to the PMIC.

The Page 0 and Page 4 register CRC has two components: include persist and exclude persist. As shown in Table 5-4, the include persist CRC information is stored in registers 0xF0 and 0xF1 of page 0 and the exclude persist is stored in registers 0xF2 and 0xF3 of page 0.

Table 5-4 User Registers (Page 0 and Page 4) Register CRC registers
Register Address, Page 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

The CRC calculation shown in the following code-snippet is taken from the Scalable PMIC GUI (see Reference 3). Appendix C is provided as an array of the register information. The information associated with the watchdog is mapped to the appropriate locations and registers are populated with default settings if not backed by NVM and with 0x00, if undefined.


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];
    }
}