工具/软件:
我有一个定制板。 我通过 i2c 将电量监测计与 STM32 MCU 进行通信。 我将 I2C 与 DMA 搭配使用。 实际上、我已成功连接、可以解封 电量计、但我无法 以任何方式进入完全访问模式。 我的步骤 在文档中是相同的。
//宏
#define BQ28Z610_UNSEAL_KEY_1 0x0414
#define BQ28Z610_UNSEAL_KEY_2 0x3672
#define BQ28Z610_FULL_ACCESS_KEY_1 0xFFFF
#define BQ28Z610_FULL_ACCESS_KEY_2 0xFFFF
#define BQ28Z610_SEAL_COMMAND 0x0030
//枚举:
_BQ28Z610_REG_CMD_CONTROL = 0x00、
_BQ28Z610_REG_CMD_SELECT_SUBCLASS = 0x3E、// ALT_MANUFACTURER_ACCESS_2_
//我在 init 中调用方法
bq28z610_drv_control_status_t _status;
memset (&_status、0、sizeof (_status));
IF (bq28z610_drv_ReadControlStatus (self、&_status))
{
uint8_t _sec_0_1_val =(_status.raw >> 13)& 0x3;// 14.1.1 0x00/01 ManufacturerAccess () 和 ControlStatus () 表
if(!_sec_0_1_val)
{
bq28z610_Seal (self);
vTaskDelay (PDMs_to_ticks (5000));
}
}
//解封
IF (bq28z610_unseal (self))
{
vTaskDelay (PDMs_to_ticks (100));
IF (bq28z610_CheckSecurityMode (self、_BQ28Z610_SECURITY_MODE_UNSEALED、1000))
{
//完全访问
IF (bq28z610_FullAccess (self))
{
vTaskDelay (PDMs_to_ticks (100));
IF (bq28z610_CheckSecurityMode (self、_BQ28Z610_SECURITY_MODE_FULL_ACCESS、1000))
{
//操作
}
}
//密封
IF (bq28z610_Seal (self))
{
vTaskDelay (PDMs_to_ticks (100));
IF (bq28z610_CheckSecurityMode (self、_BQ28Z610_SECURITY_MODE_SEALED、1000))
{
//操作
}
}
}
}
//我称之为方法
bool bq28z610_unseal (bq28z610_drv_t *self)
{
IF (NULL =self)
返回 false;
if(!bq28z610_drv_WriteWordLE (self、_BQ28Z610_REG_CMD_CONTROL、BQ28Z610_UNSEAL_KEY_1))
返回 false;
vTaskDelay (PDMs_to_ticks (30));
if(!bq28z610_drv_WriteWordLE (self、_BQ28Z610_REG_CMD_CONTROL、BQ28Z610_UNSEAL_KEY_2))
返回 false;
vTaskDelay (PDMs_to_ticks (10));
返回 true;
}
bool bq28z610_Seal (bq28z610_drv_t *self)
{
IF (NULL =self)
返回 false;
if(!bq28z610_drv_WriteWordLE (self、_BQ28Z610_REG_CMD_SELECT_SUBCLASS、BQ28Z610_SEAL_COMMAND))
返回 false;
vTaskDelay (PDMs_to_ticks (10));
返回 true;
}
bool bq28z610_FullAccess (bq28z610_drv_t *self)
{
IF (NULL =self)
返回 false;
if(!bq28z610_drv_WriteWordLE (self、_BQ28Z610_REG_CMD_SELECT_SUBCLASS、BQ28Z610_UNSEAL_KEY_1))
返回 false;
vTaskDelay (PDMs_to_ticks (30));
if(!bq28z610_drv_WriteWordLE (self、_BQ28Z610_REG_CMD_SELECT_SUBCLASS、BQ28Z610_UNSEAL_KEY_2))
返回 false;
vTaskDelay (PDMs_to_ticks (10));
返回 true;
}
bool bq28z610_CheckSecurityMode (bq28z610_drv_t *self、bq28z610_security_mode_t req、uint32_t to)
{
IF (NULL =self)
返回 false;
bq28z610_drv_control_status_t _status;
memset (&_status、0、sizeof (_status));
uint32_t _starting_time = xTaskGetTickCount ();
while (xTaskGetTickCount ()-_starting_time)< to)
{
IF (bq28z610_drv_ReadControlStatus (self、&_status))
{
uint8_t _sec_0_1_val =_status.raw >> 13;// 14.1.1 0x00/01 ManufacturerAccess () 和 ControlStatus () 表
if (((_sec_0_1_val == 0b01)&&(_BQ28Z610_security_mode_full_access == req)//完全访问
返回 true;
否则 if ((_sec_0_1_val == 0b10)&&(_BQ28Z610_security_MODE_UNSEALED == req)// UNSEALED
返回 true;
否则 if ((_sec_0_1_val == 0b11)&&(_BQ28Z610_security_mode_sealed == req)// SEALED
返回 true;
}
vTaskDelay (PDMs_to_ticks (20));
}
返回 false;
}
bool bq28z610_drv_ReadControlStatus (bq28z610_drv_t *self、bq28z610_drv_control_status_t *status)
{
uint16_t _tmp = 0;
if(!bq28z610_drv_ReadWord (self、_BQ28Z610_REG_CMD_CONTROL、&_tmp))
返回 false;
if(!_tmp)//错误状态
返回 false;
*(uint16_t*) status =_tmp;
返回 true;
}


