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.

BQ27220: 根据例程修改design capacity失败

Part Number: BQ27220
Other Parts Discussed in Thread: BQ27426, , BQSTUDIO

您好,之前搭建demo时使用了bq27426开发板但是后来没货了,改用了这款bq27220,现在在修改电池设计容量方面遇到了问题
以下是代码

uint8_t wdata[2] = {0x00, 0x00}; 
uint8_t rdata[2] = {0x00, 0x00}; 

// reset 
wdata[0] = 0x41; wdata[1] = 0x00; 
bq27426_write_register(0x00, wdata, 2); 
HAL_Delay(4000); 

// unseal
wdata[0] = 0x14; wdata[1] = 0x04; 
bq27426_write_register(0x00, wdata, 2); 
HAL_Delay(1); 
wdata[0] = 0x72; wdata[1] = 0x36; 
bq27426_write_register(0x00, wdata, 2); 

// full acess 
wdata[0] = 0xff; wdata[1] = 0xff; 
bq27426_write_register(0x00, wdata, 2); 
HAL_Delay(1); 
bq27426_write_register(0x00, wdata, 2); 
HAL_Delay(1); 

// enter cfg update mode 
wdata[0] = 0x90; wdata[1] = 0x00; 
bq27426_write_register(0x00, wdata, 2); 
uint8_t data = 0; 
do { 
    bq27426_read_register(0x3b, &data, 1); 
} while ((data & 0x04) == 0); 

// get access to design capacity 
wdata[0] = 0x9f; wdata[1] = 0x92; 
bq27426_write_register(0x3e, wdata, 2);
HAL_Delay(1); 

// read design capacity
uint8_t old_design_capacity[2] = {0};
bq27426_read_register(0x3c, old_design_capacity, 2); 
uint8_t old_sum = 0; 
bq27426_read_register(0x60, &old_sum, 1); 
uint8_t old_len = 0; 
bq27426_read_register(0x61, &old_len, 1); 


uint32_t bat_cap = 1200; // mah 

// write new design capacity 
uint8_t new_design_capacity[2] = {0}; 
new_design_capacity[0] = (bat_cap >> 8) & 0xff; 
new_design_capacity[1] = bat_cap & 0xff; 
bq27426_write_register(0x40, new_design_capacity, 2);
HAL_Delay(1); 

// calculate checksum 
uint8_t temp = mod(255 - old_sum 
                       - old_design_capacity[0] 
                       - old_design_capacity[1], 256);
uint8_t new_sum = 255 - mod(temp + new_design_capacity[0] 
                                 + new_design_capacity[1], 256); 
                                 
// write data length and new sum 
uint8_t cs[2] = {new_sum, 0x24}; 
bq27426_write_register(0x60, cs, 2);
HAL_Delay(1); 

//exit cfg update 
wdata[0] = 0x92; wdata[1] = 0x00; 
bq27426_write_register(0x00, wdata, 2); 
do { 
    bq27426_read_register(0x3b, &data, 1); 
} while ((data & 0x04) != 0); 
bq27426_sealed(); 
HAL_Delay(1); 

//read design capacity 
bq27426_read_register(0x3c, rdata, 2); // doesn't change to 1200

有以下几点疑问:
1. reset需要等待多久?这边测试是4秒,但是在文档是找不到关于这个的说明
2. 0x3e和0x3f是什么地址?
3. ManufacturerAccessControl() 和 ManufacturerAccess()分别是什么?就是0x3e和0x3f吗?因为我发现写0x0001(device_number)到0x00(Control),从0x3e读4个字节,前两个是0x0001即subcommand,两个则是device_number(MACData 0x40 0x41)
4. 为什么修改design capacity需要写入0x929f到0x3e,这和读0x3c有什么不同吗?为什么写完0x3e后从MACData读到的design capacity和读0x3c得到的design capacity他们的字节顺序是相反的?读MACData是0xb80b,而读0x3c则是正常的0x0bb8(默认值dec=3000)?
5. 为什么写0x929f到0x3e后,写新值design capacity(hex: 0x04b0, dec: 1200)到MACData也是高字节在前(0x40 0x04)低字节在后(0x41 0xb0)?是文档有误还是确实是这样设计的?
6. checksum是如何计算的?65页example的说法是计算BlockData(MACData和BlockData是同一个吗)所有32个字节的和的模?然后用255减去它?而根据25页MACDataSum()的描述还要加上ManufacturerAccessControl(),哪个说法是正确的?
7. MACDataLen()如何计算?25页描述说应该是MACData()在MACDataSum()里面的个数,为什么reset后默认MACDataLen=0x24(dec: 36),MACData()不是最多32个字节吗?

关于代码里unseal及进入cfg update,分别通过检查operation status的sec[1:0]和CFGUPDATE确认了,这部分应该没有问题,但是一直写不进去的原因我猜测可能就是checksum算不对,能帮忙给个正确的计算方式吗?以及最新的手册。SLUUBD4这个手册是2016年更新的,还是Initial Release版本,里面太多自相矛盾、错误以及解释不全的地方了,谢谢!

  • 您好,1, 请看一下B.1.3 Wait Command 

    2,3,4,5,design capacity设置请参考下面链接:

    e2e.ti.com/.../bq27220-set-design-capacity

    6,The check sum is the 255 - the 8bit wide sum of the starting address and the block bytes.

    Example:

    W: AA 3E B4 91 FD 00 00 03 00 00 00 00 CB D4 1A 05 D4 86 4A C6 B4 C2 6E 2B 03 7C 01 48 FD A3 F6 75 12 58 2D B7

    W: AA 60 62 24

    Adding up B4 91 ... B7 equals 0D9D, so the check sum is 0xFF - 0x9D = 0x62

    7,The data length contains the 2 bytes address (register 0x3E/0x3F) and the check-sum register (0x60) and length register (0x61). So the total is 36 bytes.

    Note that the example in 6.1, step 13 also shows a length of 0x24 = 36 bytes.

    checksum计算请参考下面链接的内容。

    e2e.ti.com/.../bq27220-bq27220-checksum-calculation

  • 谢谢您的回复。

    根据您的建议我尝试修改checksum和length,但是依然不能成功修改design capacity。

    我尝试了以下两种方法来设置design capacity为24mah:

    1. 先写0x929f到0x3e,接着写0x0018到0x40,checksum = 0xff - (0xff & (0x9f + 0x92 + 0x00 + 0x18)),length = 0x06。

    2.先写0x929f到0x3e,接着读0x40到0x5f到blockdata共32个字节,然后替换掉blockdata的0x40与0x41分别变成0x00, 0x18,checksum = 0xff - (0xff & (0x9f + 0x92 + checksum)),length = 0x24。

    在做完以上操作后,无论退出cfg update与否,均无法直接读0x3c或是写0x929f后读到修改后的值,可以帮忙看看是怎么回事吗?谢谢

  • checksum = 0xff - (0xff & (0x9f + 0x92 + blockdata))

  • 以下代码是把Operation Config A的sleep标志位置0,禁能sleep模式

    包括unseal->get full access->enter cfg config->write->exit cfg config and reinit->get full access->enter cfg config->read一系列较为完整的步骤,依旧无法成功写入寄存器,非常困惑

    	uint8_t wdata[2] = {0x00, 0x00};
    	uint8_t rdata[2] = {0x00, 0x00};
    
    	// unseal
    	wdata[0] = 0x14; wdata[1] = 0x04;
    	bq27426_write_register(0x00, wdata, 2);
    	HAL_Delay(1);
    	wdata[0] = 0x72; wdata[1] = 0x36;
    	bq27426_write_register(0x00, wdata, 2);
    	HAL_Delay(1);
    	bq27426_read_register(0x3a, rdata, 2);
    
    	// full acess
    	wdata[0] = 0xff; wdata[1] = 0xff;
    	bq27426_write_register(0x00, wdata, 2);
    	HAL_Delay(1);
    	bq27426_write_register(0x00, wdata, 2);
    	HAL_Delay(1);
    
    	bq27426_read_register(0x3a, rdata, 2);
    
    	// enter cfg update mode
    	wdata[0] = 0x90; wdata[1] = 0x00;
    	bq27426_write_register(0x00, wdata, 2);
    	HAL_Delay(2);
    	uint8_t data = 0;
    	do {
    	    bq27426_read_register(0x3b, &data, 1);
    	} while ((data & 0x04) == 0);
    	bq27426_read_register(0x3a, rdata, 2);
    
    	// config a
    	uint8_t configtx[3] = {0x06, 0x92, 0x00};
    	bq27426_write_register(0x3e, configtx, 3);
    	HAL_Delay(1);
    	uint8_t configrx[3] = {0x00, 0x00, 0x00};
    	bq27426_read_register(0x3e, configrx, 3);
    	HAL_Delay(1);
    
    	uint8_t sum = 0xff - (0xff & (0x00 + 0x06 + 0x92));
    	uint8_t sums[2] = {sum, 0x05};
    	bq27426_write_register(0x60, sums, 2);
    	HAL_Delay(1);
    
    	bq27426_read_register(0x3e, configrx, 3);
    	HAL_Delay(1);
    
    	//exit cfg update
    	wdata[0] = 0x91; wdata[1] = 0x00;
    	bq27426_write_register(0x00, wdata, 2);
    	HAL_Delay(1);
    	do {
    	    bq27426_read_register(0x3b, &data, 1);
    	} while ((data & 0x04) != 0);
    	HAL_Delay(1);
    	bq27426_read_register(0x3a, rdata, 2);
    	HAL_Delay(1);
    
    	do {
    		bq27426_read_register(0x3a, rdata, 2);
    	} while (!(rdata[0] & 0x20));
    	HAL_Delay(1);
    
    	// full acess
    	wdata[0] = 0xff; wdata[1] = 0xff;
    	bq27426_write_register(0x00, wdata, 2);
    	HAL_Delay(1);
    	bq27426_write_register(0x00, wdata, 2);
    	HAL_Delay(1);
    
    	// enter cfg update mode
    	wdata[0] = 0x90; wdata[1] = 0x00;
    	bq27426_write_register(0x00, wdata, 2);
    	HAL_Delay(2);
    	do {
    	    bq27426_read_register(0x3b, &data, 1);
    	} while ((data & 0x04) == 0);
    	HAL_Delay(1);
    	bq27426_read_register(0x3a, rdata, 2);
    	HAL_Delay(1);
    
    	wdata[0] = 0x06; wdata[1] = 0x92;
    	bq27426_write_register(0x3e, wdata, 2);
    	HAL_Delay(1);
    	bq27426_read_register(0x3e, configrx, 3);
    	HAL_Delay(1);

  • 您好,您用BQSTUDIO读一下,看一下芯片是不是进入保护状态所以不能修改参数。

  • 我们采用的是bq27220这款芯片,已经贴在我们自己设计的pcb板子上了,没有开发板,能使用这个bqstudio吗?另外看起来您可能是在美国,我在中国,是否有时差相近的一些技术支持能够提供?非常感谢!

  • 您好,不连接BQSTUDIO您也可以读一下Battery Status看一下当前的状态。

  • 谢谢您的回复,目前初步成功写到了!

    还有几个问题希望您能解答下

    1. 在写操作完成后(写完checksum及length后),如果需要确认是否成功修改,是:

    1)直接读对应的地址,比如修改sleep是写operation config A(0x9206) 的对应位,读battery status(0x0A 和 0x0B)

    2)还是继续写对应address到0x3e和0x3f再读MACData()

    3)还是说以上两种都可以?需要退出cfg update mode及reinit再读吗?

    2. 连续运行很难进入full access,单步调试就很轻松,这个是为什么?

  • 您好,建议您实际操作一下确认是不是两种都可以。

    请确保在没有任何中断的情况下发出解锁和full access的请求。建议您尝试使用bqStudio的相同序列,看看他们是否可以看到相同的问题。