This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] BQ76942:无法进入完全访问模式以进行 OTP 编程。 求助!

Guru**** 1797760 points
Other Parts Discussed in Thread: BQ76942
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/power-management-group/power-management/f/power-management-forum/1428556/bq76942-cannot-enter-full-access-mode-for-otp-programming-help

器件型号:BQ76942

工具与软件:

我正在使用 BQ76942、并尝试使用 OTP 编程、但无法进入完全存取模式。  

数月来、我一直在这些电路板上使用这种芯片、没有出现任何问题。 硬件工作正常并且很好理解。  

TRM 中的第125页描述了 数据存储器访问的过程、我认为我执行正确。 我已经将 LA 作为支票进行了验证。 我会添加此代码、以便您查看。  

要进入 FULL ACCESS 模式、IC 必须处于什么状态(而不是先打开 UNSEALED)。 我是否在完成进入完全访问权限的过程之前或之后输入 CFG_UPDATE? 我应该在之前还是之后进行寄存器复位?  

任何你能提供的帮助都是感激的! 我会包含相关代码。 也许在这方面会有一些容易的错误。  

FULLACCESS 的函数调用:

CommandSubcommands(BQ769x2_RESET);  // Resets the BQ769x2 registers

	    	writeDataMemoryAccess(0x9257, 0x0414, 2);
	    	delayUS(60000);
	    	writeDataMemoryAccess(0x9259, 0x3672, 2);
	    	delayUS(60000);
	    	writeDataMemoryAccess(0x925B, 0xFFFF, 2);
	    	delayUS(60000);
	    	writeDataMemoryAccess(0x925D, 0xFFFF, 2);
	    	delayUS(60000);

	    	uint8_t battery_status_data = checkBQAccessMode();
			if(battery_status_data != 4)
			{
//				while(1)
//				{
//					LEDControl("R", 100, 4);
//				}
			}
			delayUS(60000);

			// Enter CONFIGUPDATE mode (Subcommand 0x0090) - It is required to be in CONFIG_UPDATE mode to program the device RAM settings
			// See TRM for full description of CONFIG_UPDATE mode
			CommandSubcommands(SET_CFGUPDATE);
			delayUS(60000);

			//Use OTP_WR_CHECK() to determine if the chip is ready for OTP programming. OTP WR CHECK will return
			uint8_t otp_write_status = OTPWriteCheck();
			delayUS(60000);
			if(otp_write_status == 0X80){ //Write to the desired OTP Register and send the OTP Write command
				test = 1;
			}

writeDataMemoryAccess()函数:

void writeDataMemoryAccess(uint16_t memory_address, uint16_t value, uint8_t size){
    uint8_t address[2] = {0};
    address[0] = memory_address & 0xFF;        // Lower byte of address
    address[1] = (memory_address >> 8) & 0xFF; // Upper byte of address

    uint8_t data[32] = {0};
    uint8_t i;

    // Prepare data in little endian format
    for(i = 0; i < size; i++){
        data[i] = (value >> (i * 8)) & 0xFF;
    }

    // Prepare the buffer for checksum calculation
    uint8_t checksum_buffer[2 + size]; // 0x3E, 0x3F, and data buffer
    checksum_buffer[0] = address[0];   // 0x3E
    checksum_buffer[1] = address[1];   // 0x3F
    for(i = 0; i < size; i++){
        checksum_buffer[2 + i] = data[i]; // Data bytes starting at 0x40
    }

    // Calculate checksum using existing Checksum function
    uint8_t checksum = Checksum(checksum_buffer, 2 + size);

    // Length calculation: data length + 4 (for 0x3E, 0x3F, 0x60, 0x61)
    uint8_t length = size + 4;

    // Write lower byte of address to 0x3E
    I2C_WriteReg(0x3E, &address[0], 1);
    // Write upper byte of address to 0x3F
    I2C_WriteReg(0x3F, &address[1], 1);
    // Write data to 0x40
    I2C_WriteReg(0x40, data, size);
    // Write checksum to 0x60
    I2C_WriteReg(0x60, &checksum, 1);
    // Write length to 0x61
    I2C_WriteReg(0x61, &length, 1);
}

I2C_WriteReg ()函数只是直通 Mem_Write 32 HAL_I2C_STM32 ()函数。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Ryan、您好!

    只是为了澄清、器件是否已解封? 您以前是否能够进入完全访问模式?

    此致、
    Alexis

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Alexis:  

    好的、那么事实证明这是我的代码中的一个问题。 我使芯片处于完全访问 状态、并且电池状态寄存器的位7为0。  

    不过、当我将芯片放入 CFG 时、OTP_WR_STATUS 寄存器读取为0xFF。 这可能是什么原因造成的? 在我把芯片放入 CFG 更新前、读数为0x20 (我认为是因为我们不在 CFG 更新中)。  

    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    如果有任何方法,我们可以很快得到一些信息,我会非常感谢它! 我正处在一个时间紧迫的时刻,以解决和测试这一问题。 提前感谢。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Ryan、您好!

    您读取寄存器的速度可能过快。   您是否能够在读取结果之前尝试添加2ms 的等待时间、看看这是否有帮助?

    首选 2个子命令  BQ769x2软件开发指南(修订版 B)中 讨论了这方面的内容。

    此致、
    Alexis

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Alexis、  

    我在每次 I2C 事务变得安全之前增加了2ms 的延迟。 这似乎没有什么区别。  

    以下是我的代码以便为您提供帮助。  

    显然、芯片似乎无法准确报告0xFF、因为这会指示欠压和过压、过热和欠温等  

    //Create some flags to diagnose OTP
    	    	uint8_t shutdown_stack_voltage_alread_written, not_in_full_access, registers_not_programmed_successfully, otp_wr_check_nfg, OTPB_write_bit_data_nfg;
    
    	    	/*
    	    	1. Check whether OTP programming has already been done on the device by reading one of the programmed
    	    	registers. When power is applied, registers will either report the default values or the values programmed in
    	    	OTP if OTP has been programmed. If OTP programming has not been done, proceed to the next steps.
    			*/
    	    	uint8_t data[2];
    	    	HAL_Delay(2);
    	    	BQ769x2_GetRegister(ShutdownStackVoltage, data, 2);
    	    	uint16_t shutdown_stack_voltage = ((data[1] << 8) | data[0]) * 10; //reports in mA
    
    	    	//2. Read the 0x12 Battery Status[SEC1,SEC0] bits to verify the device is in FULL ACCESS mode (0x01).
    	    	HAL_Delay(2);
    			writeDataMemoryAccess(0x9257, 0x0414, 2);
    			delayUS(60000);
    			writeDataMemoryAccess(0x9259, 0x3672, 2);
    			delayUS(60000);
    			writeDataMemoryAccess(0x925B, 0xFFFF, 2);
    			delayUS(60000);
    			writeDataMemoryAccess(0x925D, 0xFFFF, 2);
    			delayUS(60000);
    
    			HAL_Delay(2);
    	    	uint8_t battery_status_data = checkBQAccessMode();
    	    	if(battery_status_data != 0x01){
    	    		not_in_full_access = 1;
    	    	}
    
    	    	//3. If the device is in FULL ACCESS mode, enter CONFIG_UPDATE mode - (Subcommand 0x0090).
    	    	HAL_Delay(2);
    	    	CommandSubcommands(SET_CFGUPDATE);
    
    	    	//4. Configure the register settings in data memory.
    	    	HAL_Delay(2);
    	    	uint32_t shutdown_stack_voltage_data = 1680; //Shutdown stack voltage in units of 10mV
    	    	BQ769x2_SetRegister(ShutdownStackVoltage, shutdown_stack_voltage_data, 2);
    
    	    	//5. Exit CONFIG_UPDATE mode - (Subcommand 0x0092).
    	    	HAL_Delay(2);
    	    	CommandSubcommands(EXIT_CFGUPDATE);
    
    	    	//6. Read the data memory registers to verify all parameters were written successfully.
    	    	HAL_Delay(2);
    	    	BQ769x2_GetRegister(ShutdownStackVoltage, data, 2);
    	    	shutdown_stack_voltage = ((data[1] << 8) | data[0]) * 10; //reports in mA
    
    	    	//7. Enter CONFIG_UPDATE mode.
    	    	HAL_Delay(2);
    	    	CommandSubcommands(SET_CFGUPDATE);
    
    	    	//8. Check the Battery Status[OTPB] bit is clear to verify OTP programming conditions are met.
    	    	HAL_Delay(2);
    	    	uint8_t OTPB_write_bit_data = checkBQ_OTPB_Bit();
    	    	if(OTPB_write_bit_data != 1){
    	    		OTPB_write_bit_data_nfg = 1;
    	    	}
    
    	    	//9. Read OTP_WR_CHECK() (Subcommand 0x00A0). If this returns a value of 0x80, then OTP programming
    	    	//conditions are met.
    	    	HAL_Delay(2);
    	    	uint8_t otp_write_status = OTPWriteCheck();
    	    	if(otp_write_status == 0x80){
    	    		//Execute the OTP write
    	    	}
    	    	else otp_wr_check_nfg;
    
    	    	//10. If OTP_WR_CHECK indicates conditions are met, send OTP_WRITE() subcommand (0x00A1).
    
    
    	    	//11. Wait 100 ms. Read from 0x40 to check if OTP programming was successful (0x80 indicates success).
    	    	HAL_Delay(200);

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Ryan、您好!

    您能否向我发送每个步骤的逻辑分析仪捕获结果(.sal 文件)?

    另外、我知道一些用户已经添加了最长10ms 和100ms 以确保安全处理命令。 以下是一个示例: BQ76952:OTP 故障。 您能否试着增加时间、看看这是否也有帮助?

    此致、
    Alexis

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Alexis、  

    我没有 Salae 分析仪(我正在使用 PulseView 对其进行抽卷。) 您能否打开 PulseView 输出? 我正在连接它。 如果没有,让我尽快知道,我将把一些屏幕截图放在一起。  

    e2e.ti.com/.../Logic-Output-_2800_short-delay-code_2900_.zip

    此致!  
    Ryan  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Ryan、您好!

    很遗憾、我无法从 PulseView 查看文件。 你能告诉我增加时间是否也起作用吗?

    此致、
    Alexis

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Alexis、很抱歉这么晚才回复。 是的、我终于找到了延迟不足的地方。 写入0x3e/0x3f 寄存器后、从0x60读取之前该计数不足。 我将发布这段代码、以防将来有人能从中受益。 感谢您的配合。  

    uint8_t OTPWrite(){
    	uint16_t command = OTP_WRITE;
    
    	//security keys and Manu_data writes dont work with this function (reading these commands works)
    	//max readback size is 32 bytes i.e. DASTATUS, CUV/COV snapshot
    	uint8_t TX_Reg[4] = { 0x00, 0x00, 0x00, 0x00 };
    	uint8_t TX_Buffer[2] = { 0x00, 0x00 };
    
    	//TX_Reg in little endian format
    	TX_Reg[0] = command & 0xff;
    	TX_Reg[1] = (command >> 8) & 0xff;
    
    	//Access the register data
    	I2C_WriteReg(0x3E, TX_Reg, 2);
    	delayUS(100000);
    	I2C_ReadReg(0x40, RX_32Byte, 32); //RX_32Byte is a global variable
    
    	return RX_32Byte[0]>>7; //Return the bit that confirms good OTP programming
    }