ZHCU948B September 2020 – May 2022 BQ76952
SPI 事务的第一个字节包含一个 R/W 位(R=0,W=1),后跟一个 7 位地址,MSB 在最前面。如果控制器(主机)正在写入,第二个字节将是要写入的数据。如果控制器正在读取,将忽略 SPI_MOSI 上发送的第二个字节(CRC 计算除外)。
如果启用了 CRC,控制器必须将 8 位 CRC 代码作为第三个字节发送,该代码是通过前两个字节计算得出的。如果 CRC 正确,会将在时钟沿输入的值放入接收缓冲区。如果 CRC 不正确,会将发送缓冲区设置为 0xFFFF,并将发送的 CRC 设置为 0xAA(在下一个事务的时钟沿输出)。
在此事务期间,逻辑将在时钟沿输出发送缓冲区的内容。如果自上次事务以来未更新发送缓冲区,逻辑将在时钟沿输出 0xFFFF,如果在时钟沿进行 CRC,CRC 将在时钟沿输出 0x00(如启用)。因此,0xFFFF00 将向控制器指示发送缓冲区在事务发生之前未被内部逻辑更新。当器件没有足够的时间更新连续事务之间的缓冲区时,就会发生这种情况。
当内部逻辑从接口逻辑中获取写入数据并对其进行处理时,该内部逻辑还会将 R/W 位、地址和数据复制到发送缓冲区中。在下一个事务中,此数据将在时钟沿被发送回控制器。
当控制器开始读取时,内部逻辑会将 R/W 位和地址连同请求的数据一起放入发送缓冲区中。如果启用了 CRC,接口将对发送缓冲区中的两个字节计算 CRC,并在时钟沿将结果返回至控制器(如上所述,与 0xFFFF 相关的异常情况)。下面显示了使用 CPOL=0 时,三个使用 CRC 和不使用 CRC 的事务序列图。
器件处理命令和子命令所需的时间将根据每个命令的具体情况而有所不同。例如,当发送 0x0071 DASTATUS1() 子命令时,器件需要大约 200μs 才能将 32 字节的数据加载到内部子命令缓冲区。如果主机在开始读取缓冲区(从地址 0x40 读回地址 0x5F)之前提供足够的时间完成此加载,器件将使用有效数据而不是 0xFFFF00 进行响应。当数据已经加载到子命令缓冲区时,可以在 SPI 事务之间以大约 50μs 的间隔读回该数据。
主机软件应包含重试可能不成功的事务的方案。例如,如果器件在 SPI_MISO 上返回 0xFFFFFF,说明内部时钟未通电,需要重试事务。类似地,如果器件在一个事务上返回 0xFFFFAA,这表明以前的事务遇到 CRC 错误,因此必须重试前一个事务。如上所述,如果器件返回 0xFFFF00,说明当前事务发送时之前的事务尚未完成,这可能意味着应该重试之前的事务,或者至少需要更多的时间才能完成。
根据特定命令或子命令完成操作所需的大致时间如下所示。请注意,这些时间只是近似值,可能会因当时的系统操作而变化。因此,主机处理器必须包含来自主机处理器的重试方案,以处理操作期间可能发生的通信错误或延迟。
命令/子命令地址 | 命令/子命令名称 | 完成操作的时间(近似值) |
---|---|---|
0x00 | Control Status() | 50μs |
0x02 - 0x07 | Safety Alert() 和 Safety Status() | 50μs |
0x0A-0x11 | PF Alert() 和 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 |
009x0D | 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 和 LO 子命令 | 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 |