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.

BQ40Z50-R2: Reading OCC1 and OCD1 Threshold values from Data Flash using ManufacturerBlockAccess( )

Part Number: BQ40Z50-R2
Other Parts Discussed in Thread: BQ40Z50

Tool/software:

Hey, so I have been trying to read the OCC1(Overcurrent during Charge 1) and OCD1(Overcurrent during Discharge 1) Thresholds from Data Flash. I started with OCC1 first. Now the address for OCC1 Threshold given in the Data Flash table on the Technical Reference Manual is 0x495E.

Now, according the Technical Reference Manual to access Data Flash, one can do that only by using ManufacturerBlockAccess( ) '0x44' by addressing the physical address.

The entire process of reading a particular value has been divided into two parts, in the manual as follows:- 

Taking the same assuming from the read DF example, to read DF,

a. Send SMBus write block with command 0x44, block = 0x00 + 0x40

b. Send SMBus read block with command 0x44 The returned block = a starting address + 32 bytes of DF data = 0x00 + 0x40 + data1_LowByte + data1_HighByte + data2_LowByte + data2_HighByte.... data32_LowByte + data32_HighByte

As mentioned before the address for OCC1 Threshold given in the manual is 0x495E, so I used it and followed the same procedure as showed in the example from manual shared above. 
I tried doing the read in an Arduino Sketch using I2C from an ESP32 WROOM 32E, but the data that was returned, I think was not at all correct, and it wasn't even in accordance with the returned block structure as shown above like the first two bytes being the LSB and MSB of the address that was sent initially using write block. The default value given for the OCC1 Threshold was 6000mA in the manual whose hexadecimal representation should be 0x1778, and if thats the case and also taking into consideration that a block read performed using ManufacturerBlockAccess( ) returns data in little endian then I should be getting 0x1778 somewhere in the entire 34 bytes that is being sent out as 0x70(LSB) + 0x17(MSB), but that's nowhere to be found. 

I am attaching my Arduino Sketch, Its output as seen on a Serial Terminal, and few screenshots from the Technical Reference Manual. Please me help figure this problem out, and let me know what else needs to be done in the code.

Arduino Sketch:-

#include "Wire.h"

#define ESP32
#define BQ_ADDR 0x0B
#define MFG_BLOCK_ACC 0x44// MANUFACTURER BLOCK ACCESS COMMAND
#define LSB 0x5E// LSB OCC1 THRESHOLD ADDRESS
#define MSB 0x49// MSB OCC1 THRESHOLD ADDRESS
#if defined(ESP32)
#define SDA 21
#define SCL 22
#elif defined(ESP32S3)
#define SDA 8
#define SCL 9
#endif
void setup() {
  // put your setup code here, to run once:
  uint8_t HW_b[34];
  Serial.begin(115200);
  Wire.begin(SDA,SCL);
  Wire.beginTransmission(BQ_ADDR);
  Wire.write(MFG_BLOCK_ACC);// SENDING WRITE BLOCK WITH COMMAND 0x44
  Wire.write(LSB);// LSB OCC1 THRESHOLD ADDRESS
  Wire.write(MSB);// MSB OCC1 THRESHOLD ADDRESS
  Wire.endTransmission();
  delay(1000);
  
  Wire.beginTransmission(BQ_ADDR);
  Wire.write(MFG_BLOCK_ACC);// SENDING READ BLOCK WITH COMMAND 0x44
  Wire.requestFrom(BQ_ADDR,34);
  delay(100);
  Serial.println("Returning all bytes in little endian");
  for(int i = 0; i<34;i++){
    if(Wire.available()){
    HW_b[i]=Wire.read();
    Serial.print("Byte ");
    Serial.print(i);
    Serial.print(": 0x");
    Serial.println(HW_b[i],HEX);
    }
  }
  Wire.endTransmission();
}

void loop() {
  // put your main code here, to run repeatedly:

}

Output on Serial Terminal:-

Screenshots from Technical Reference Manual:-

       

Thanks

  • Hello,

    Can you confirm whether the device is in an unsealed state at the time of the DF reading?

    If possible, can you please share a logic analyzer capture of the communication when these commands are sent?

    Regards,

    Anthony

  • Hello,
    Yeah so I did read the Operation Status(0x0054) using Manufacturer Access both before and after flashing the Arduino Sketch to UNSEAL the BQ40Z50 but both the read returned the exact same 4 Bytes with no changes in them at all. The read yielded 0x00 0x54 0x1F 0x1F(that is all in little endian) so the actual read would be 0x1F1F5400 and in binary it is 0001 1111 0001 1111 0101 0100 0000 0000, now as per the technical reference SEC 0 and SEC 1 of Operation Status tell us if the device is SEALED or not. SEC 1(Bit 9) while SEC 0(Bit 8). 
    But as per my findings both are 0s, and as per the technical reference it would mean The Security Mode is RESERVED.

    I am sending the Arduino Sketches for both:-

    1) The Operation Status read

    #include "Wire.h"
    
    #define BQ_ADDR 0x0B
    #define MFG_ACC 0x00
    #define MFG_DAT 0x23
    #define LSB 0x54
    #define MSB 0x00
    #define SDA 21
    #define SCL 22
    
    void setup() {
      uint8_t byte[4];
      memset(byte,0,sizeof(byte));
      Serial.begin(115200);
      Wire.begin(SDA,SCL);
      Wire.beginTransmission(BQ_ADDR);
      Wire.write(BQ_ADDR);
      Wire.write(MSB);
      Wire.write(LSB);
      Wire.endTransmission();
    
      Wire.beginTransmission(BQ_ADDR);
      Wire.write(MFG_DAT);
      Wire.requestFrom(BQ_ADDR,4);
      for(int i = 0;i<4;i++){
        if(Wire.available()){
          byte[i]=Wire.read();
          Serial.print("0x");
          Serial.println(byte[i],HEX);
        }
        else Serial.println("No data available over I2C");
      } 
      Wire.endTransmission();
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    
    }
    

    2) The Program to UNSEAL the device

    #include "Wire.h"
    
    #define BQ_ADDR 0x0B
    #define MFG_ACC 0x00
    #define LSB_1 0x14
    #define MSB_1 0x04
    #define LSB_2 0x72
    #define MSB_2 0x36
    #define SDA 21
    #define SCL 22
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(115200);
      Wire.begin(SDA,SCL);
      Wire.beginTransmission(BQ_ADDR);
      Wire.write(MFG_ACC);
      Wire.write(MSB_1);
      Wire.write(LSB_1);
      delay(4000);
      Wire.write(MSB_2);
      Wire.write(LSB_2);
      Wire.endTransmission();
      Serial.println("DEVICE UNSEALED!");
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    
    }
    

    P.S:- In the code above to UNSEAL the device a delay of 4000ms was added because the technical reference manual instructed to send a delay of 4 seconds in between sending the first and the second Security Keys.

    Thanks

  • Hello,

    Here are the screen shots from the logic analyzer when the commands for reading the OCC1 threshold value from Data Flash using Manufacturer Block Access are being sent.

  • Hello,

    We have received your request and are looking into the issue. We will provide an update soon.

    Regards,

    Anthony