I am trying to read cell voltage 1 value with CRC over i2c. I am using bq76942 EVM(BMS) module as my slave device. Following is the code I am using :
The CRC I am getting through response is 0x45.
But, the correct CRC value is 0x2B according to the CRC function.
For the second byte of data, the response value is 0x23 which is correct. Any help will be appreciated.
Datasheet Please see page number 76.
-
4\$\begingroup\$ Please don't use screenshots for text-based code, we can't copy/paste it to give you a corrected version, or to try it for ourselves. \$\endgroup\$Ron Beyer– Ron Beyer2020年09月14日 15:39:04 +00:00Commented Sep 14, 2020 at 15:39
-
1\$\begingroup\$ How to read data from slave over i2c using HAL_I2C_Master_Sequential_Receive_IT? \$\endgroup\$Gaurav– Gaurav2020年09月14日 18:07:33 +00:00Commented Sep 14, 2020 at 18:07
-
1\$\begingroup\$ I think by using repeated start condition will solve my problem? My slave address is 0x08(7 bit address) . \$\endgroup\$Gaurav– Gaurav2020年09月14日 18:11:54 +00:00Commented Sep 14, 2020 at 18:11
-
1\$\begingroup\$ Please delete either this question or the one posted on StackOverflow. \$\endgroup\$Codo– Codo2020年09月14日 18:23:14 +00:00Commented Sep 14, 2020 at 18:23
-
1\$\begingroup\$ CRC implementation is correct. You can also use the online CRC calculator. According to the bq76942 datasheet. In a single-byte read transaction, the CRC is calculated beginning at the first start, so will include the slave address, the register address, then the slave address with read bit set, then the data byte. [0x10, 0x14, 0x11, 0x01] \$\endgroup\$Gaurav– Gaurav2020年09月14日 18:34:57 +00:00Commented Sep 14, 2020 at 18:34
1 Answer 1
This is due to the way the I2C function is doing a start, stop and then start. If you use a repeated start like in the Software Development guide app note (https://www.ti.com/lit/an/sluaa11/sluaa11.pdf) then the CRC would include the bytes for the first write [0x10 0x14 0x11 0x01]. However, since you are doing a stop and then a start, it seems like it will calculate CRC only on the 2nd transaction [0x11 0x01].
In ST you can use
HAL_I2C_Master_Sequential_Transmit_IT(); instead of HAL_I2C_Master_Transmit()
Code :
char cmd=0x14;
char readbuf[4]={0,0,0,0};
HAL_I2C_Master_Sequential_Transmit_IT(&hi2c1, 0x08 << 1, &cmd, 1, I2C_FIRST_FRAME);
while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY);
HAL_I2C_Master_Sequential_Receive_IT(&hi2c1, 0x08 << 1, readbuf, 4, I2C_LAST_FRAME);
while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY);