SLUUBY1B December 2020 – April 2022 BQ76942
The first byte of a SPI transaction consists of an R/W bit (R=0, W=1), followed by a 7-bit address, MSB-first. If the controller (host) is writing, then the second byte will be the data to be written. If the controller is reading, then the second byte sent on SPI_MOSI is ignored (except for CRC calculation).
If CRC is enabled, then the controller must send as the third byte the 8-bit CRC code, which is calculated over the first two bytes. If the CRC is correct, then the values clocked in will be put into the incoming buffer. If the CRC is not correct, then the outgoing buffer will be set to 0xFFFF, and the outgoing CRC will be set to 0xAA (these are clocked out on the next transaction).
During this transaction, the logic clocks out the contents of the outgoing buffer. If the outgoing buffer has not been updated since the last transaction, then the logic will clock out 0xFFFF, and if the CRC is clocked, it clocks out 0x00 for the CRC (if enabled). Thus, 0xFFFF00 indicates to the controller that the outgoing buffer was not updated by the internal logic before the transaction occurred. This can occur when the device did not have sufficient time to update the buffer between consecutive transactions.
When the internal logic takes the write-data from the interface logic and processes it, it also causes the R/W bit, address, and data to be copied into the outgoing buffer. On the next transaction, this data is clocked back to the controller.
When the controller is initiating a read, the internal logic will place the R/W bit and address into the outgoing buffer, along with the data requested. The interface will compute the CRC on the two bytes in the outgoing buffer and clock that back to the controller if CRC is enabled (with the exceptions associated with 0xFFFF as noted above). A diagram of three transaction sequences with and without CRC are shown below, assuming CPOL = 0.
The time required for the device to process commands and subcommands will differ based on the specifics of each. For example, when the 0x0071 DASTATUS1() subcommand is sent, the device requires approximately 200 μs to load the 32-byte data into the internal subcommand buffer. If the host provides sufficient time for this load to complete before beginning to read the buffer (readback from addresses 0x40 to 0x5F), the device will respond with valid data, rather than 0xFFFF00. When data has already been loaded into the subcommand buffer, this data can be read back with approximately 50 μs interval between SPI transactions. Note that some commands or subcommands may take longer than 200 μs to complete. A notable exception is the IROM_SIG() subcommand, which takes approximately 9 ms to complete.
The host software should incorporate a scheme to retry transactions that may not be successful. For example, if the device returns 0xFFFFFF on SPI_MISO, then the internal clock was not powered, and the transaction will need to be retried. Similarly, if the device returns 0xFFFFAA on a transaction, this indicates the previous transaction encountered a CRC error, and so the previous transaction must be retried. And as described above, if the device returns 0xFFFF00, then the previous transaction had not completed when the present transaction was sent, which may mean the previous transaction should be retried, or at least needs more time to complete.
The approximate time required to complete an operation based on the particular command or subcommand is shown below. Note that these times are only approximate and may vary depending on system operation at the time. Therefore, it is important that the host processor incorporate a retry scheme from the host processor, to handle communications errors or delays that may occur during operation.
Command/Subcommand Address | Command/Subcommand Name | Time to Complete Operation (approximate) |
---|---|---|
0x00 | Control Status() | 50 μs |
0x02–0x07 | Safety Alert() and Safety Status() | 50 μs |
0x0A–0x11 | PF Alert() and PF Status() | 50 μs |
0x12 | Battery Status() | 50 μs |
0x14–0x32 | Cell Voltages() | 50 μs |
0x34 | Stack Voltage() | 50 μs |
0x36 | PACK Pin Voltage() | 50 μs |
0x38 | LD Pin Voltage() | 50 μs |
0x3A | CC2 Current() | 50 μs |
0x62 | Alarm Status() | 50 μs |
0x64 | Alarm Raw Status() | 50 μs |
0x66 | Alarm Enable() | 50 μs |
0x68 | Internal Temperature() | 50 μs |
0x6A–0x7A | Thermistor Temperatures() | 50 μs |
0x0001 | DEVICE_NUMBER() | 400 μs |
0x0002 | FW_VERSION() | 400 μs |
0x0003 | HW_VERSION() | 400 μs |
0x0004 | IROM_SIG() | 8500 μs |
0x0005 | STATIC_CFG_SIG() | 450 μs |
0x0009 | DROM_SIG() | 650 μs |
0x000E | EXIT_DEEPSLEEP() | 500 μs |
0x000F | DEEPSLEEP() | 500 μs |
0x0010 | SHUTDOWN() | 500 μs |
0x001C | PDSGTEST() | 550 μs |
0x001D | FUSE_TOGGLE() | 500 μs |
0x001E | PCHGTEST() | 900 μs |
0x001F | CHGTEST() | 550 μs |
0x0020 | DSGTEST() | 550 μs |
0x0022 | FET_ENABLE() | 500 μs |
0x0024 | PF_ENABLE() | 500 μs |
0x0030 | SEAL() | 500 μs |
0x0053 | SAVED_PF_STATUS() | 500 μs |
0x0057 | MANUFACTURING STATUS() | 605 μs |
0x0070 | MANU_DATA() | 660 μs |
0x0071–0x0077 | DASTATUS1-7() | 660 μs |
0x0080 | CUV_SNAPSHOT() | 660 μs |
0x0081 | COV_SNAPSHOT() | 660 μs |
0x0082 | RESET_PASSQ() | 600 μs |
0x0083 | CB_ACTIVE_CELLS() | 560 μs |
0x0084 | CB_SET_LVL() | 480 μs |
0x0085–0x0087 | CBSTATUS1-3() | 575 μs |
0x008A | PTO_RECOVER() | 500 μs |
0x0090 | SET_CFGUPDATE() | 2000 μs |
0x0092 | EXIT_CFGUPDATE() | 1000 μs |
0x0093 | DSG_PDSG_OFF() | 550 μs |
0x0094 | CHG_PCHG_OFF() | 550 μs |
0x0095 | ALL_FETS_OFF() | 550 μs |
0x0096 | ALL_FETS_ON() | 500 μs |
0x0097 | FET_CONTROL() | 495 μs |
0x0098 | REG12_CONTROL() | 450 μs |
0x0099 | SLEEP_ENABLE() | 500 μs |
0x009A | SLEEP_DISABLE() | 500 μs |
0x009B | OCDL_RECOVER() | 500 μs |
0x009C | SCDL_RECOVER() | 500 μs |
0x009D | LOAD_DETECT_RESTART() | 500 μs |
0x009E | LOAD_DETECT_ON() | 500 μs |
0x009F | LOAD_DETECT_OFF() | 500 μs |
0x00A0 | OTP_WR_CHECK() | 580 μs |
0x2800 - 0x2818 | GPO HI and LO subcommands | 500 μs |
0x2857 | PF_FORCE_A() | 500 μs |
0x29A3 | PF_FORCE_B() | 800 μs |
0x29BC | SWAP_COMM_MODE() | 500 μs |
0x29E7 | SWAP_TO_I2C() | 500 μs |
0x7C35 | SWAP_TO_SPI() | 500 μs |
0x7C40 | SWAP_TO_HDQ() | 500 μs |
0xF081 | READ_CAL1() | 630 μs |