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.

BQ28Z610: Full Access Mode entering issue

Part Number: BQ28Z610


Tool/software:

I have a custom board. And I communicate the gauge via i2c with my stm32 mcu. I use i2c with DMA. Actually I successfully connected and i can unseal the gauge but i can't enter the full access mode in no way. My steps are same in the document.

// Macros

#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


// Enum:

_BQ28Z610_REG_CMD_CONTROL = 0x00,
_BQ28Z610_REG_CMD_SELECT_SUBCLASS = 0x3E, // ALT_MANUFACTURER_ACCESS_2​_

// I call the methods in 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() andControlStatus() table
if (!_sec_0_1_val)
{
bq28z610_Seal(self);
vTaskDelay(pdMS_TO_TICKS(5000));
}
}

// Unseal
if (bq28z610_Unseal(self))
{
vTaskDelay(pdMS_TO_TICKS(100));
if (bq28z610_CheckSecurityMode(self, _BQ28Z610_SECURITY_MODE_UNSEALED, 1000))
{
// Full Access
if (bq28z610_FullAccess(self))
{
vTaskDelay(pdMS_TO_TICKS(100));
if (bq28z610_CheckSecurityMode(self, _BQ28Z610_SECURITY_MODE_FULL_ACCESS, 1000))
{
 // Operations
}
}

// Seal
if (bq28z610_Seal(self))
{
vTaskDelay(pdMS_TO_TICKS(100));
if (bq28z610_CheckSecurityMode(self, _BQ28Z610_SECURITY_MODE_SEALED, 1000))
{
 // Operations
}
}
}
}



// I called methods

bool bq28z610_Unseal(bq28z610_drv_t *self)
{
if (NULL == self)
return false;

if (!bq28z610_drv_WriteWordLE(self, _BQ28Z610_REG_CMD_CONTROL, BQ28Z610_UNSEAL_KEY_1))
return false;

vTaskDelay(pdMS_TO_TICKS(30));
if (!bq28z610_drv_WriteWordLE(self, _BQ28Z610_REG_CMD_CONTROL, BQ28Z610_UNSEAL_KEY_2))
return false;
vTaskDelay(pdMS_TO_TICKS(10));
return true;
}

bool bq28z610_Seal(bq28z610_drv_t *self)
{
if (NULL == self)
return false;

if (!bq28z610_drv_WriteWordLE(self, _BQ28Z610_REG_CMD_SELECT_SUBCLASS, BQ28Z610_SEAL_COMMAND))
return false;

vTaskDelay(pdMS_TO_TICKS(10));
return true;
}

bool bq28z610_FullAccess(bq28z610_drv_t *self)
{
if (NULL == self)
return false;

if (!bq28z610_drv_WriteWordLE(self, _BQ28Z610_REG_CMD_SELECT_SUBCLASS, BQ28Z610_UNSEAL_KEY_1))
return false;

vTaskDelay(pdMS_TO_TICKS(30));
if (!bq28z610_drv_WriteWordLE(self, _BQ28Z610_REG_CMD_SELECT_SUBCLASS, BQ28Z610_UNSEAL_KEY_2))
return false;
vTaskDelay(pdMS_TO_TICKS(10));
return true;
}

bool bq28z610_CheckSecurityMode(bq28z610_drv_t *self, bq28z610_security_mode_t req, uint32_t to)
{
if (NULL == self)
return 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() andControlStatus() table
if ((_sec_0_1_val == 0b01) && (_BQ28Z610_SECURITY_MODE_FULL_ACCESS == req)) // Full access
return true;
else if ((_sec_0_1_val == 0b10) && (_BQ28Z610_SECURITY_MODE_UNSEALED == req)) // Unsealed
return true;
else if ((_sec_0_1_val == 0b11) && (_BQ28Z610_SECURITY_MODE_SEALED == req)) // Sealed
return true;
}
vTaskDelay(pdMS_TO_TICKS(20));
}
return 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))
return false;
if (!_tmp) // Error status
return false;
*(uint16_t*)status = _tmp;
return true;
}