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.

BQ34Z100-G1: Programming DFFS with host micro always bricks fuel gauge

Part Number: BQ34Z100-G1
Other Parts Discussed in Thread: BQ27510-G3, BQ27510, BQSTUDIO, BQ34Z100

Hello!

I was previously using BQ27510-G3 and was successfully using my host microcontroller (ATMega2560) to program the DFFS file on the bq27510.

We changed our design and now use a BQ34Z100. Because the commands to enter ROM mode and the DFFS file structure did not change, I kept my code the same as was used with the bq27510. I confirmed the new chip is entering ROM mode (successfully ACKs 0x16 address); however, if I try to program the gauge it will always end up bricked and unable to communicate with BQstudio. If I program the same golden image to the device using bqstudio before attempting my onboard programming, the programming does not brick the fuel gauge and does work (confirmed the resistor divider value (and consequently the reported voltage) changes if a different image is used). What could be going on?

I was reading through the forum and found several posts about bq34z100 bricking after DFFS upload due to the LED configuration. I confirmed that mode was set to 0 (no LED) and still no luck.

 

I'm attaching the exported data registers when programmed correctly with BQStudio, and a snippet of code with all the relevant sections to program the gauge. The site is not allowing my to upload any of the golden image files (dffs, srec, bqfs); however, I uploaded a .txt file that is the Data Block section of the dffs file in an array format so it can be compiled into my C code. The format of this file is first element is the total number of commands (or lines in the dffs file), then each row of the dffs file is converted into a string of integers - the first being the length of values making up that command, the second is the command code (W, C, X) and last are the data value bytes.

Hope that was clear. Let me know if you have any questions or see any potential explanation for the bricking.

20230816_SW048D_LEDHoldTime0.gg.csv

// Device I2C addresses
#define CHARGER_ADDR 0xD0
#define GAUGE_ADDR 0xAA

#define GAUGE_ADDR_ROMMODE 0x16
#define GAUGE_ROMMODE_REG 0x64

// Gauge Commands
#define GAUGE_CMD_TTE 0x16    // standard commands
#define GAUGE_CMD_VBAT 0x08
#define GAUGE_CMD_IBAT 0x10
#define GAUGE_CMD_CAP 0x02
#define GAUGE_CMD_CYCLE 0x2C
#define GAUGE_CMD_DCAP 0x2E

#define GAUGE_CMD_CONTROL 0x00      // control() subcommands
#define GAUGE_DEVICE_TYPE 0x0001
#define GAUGE_SET_HIBERNATE 0x0011
#define GAUGE_CLR_HIBERNATE 0x0012
#define GAUGE_SET_INSERT 0x000D  
#define GAUGE_RESET 0x0041
#define GAUGE_CTRL_STATUS 0x0000
#define GAUGE_SET_SLEEPP 0x0013
#define GAUGE_DIS_SLEEPP 0x0014

// Gauge Status Types
#define BAT_SHORT_FAULT 1
#define BAT_MISSING_FAULT 2
#define MAX_CHARGE_TIME_FAULT 4
#define CHARGER_SUSPENDED 256
#define BAT_DETECT_FAILED 4096

/******************************************************************************\
 * Gauge specific command functions
\******************************************************************************/


/******************************************************************************
* Reads nLength bytes from gauge and stores reading in buffer. Returns 0 when
* all operations were successful; non-zero otherwise.
*
*   Called by battery_update(), gauge_control(), and gauge_set_pfc_mode().
*
*   @param addr     i2c device address
*   @param cmd      first register (i.e. standard command) to read from
*   @param *pData   pointer to a data buffer (array)
*   @param nLength  number of bytes to read
******************************************************************************/
void gauge_program_start()
{
	// local variables to hold read status
	uint16_t status_out = 0;
	uint8_t status_msb = 0;
			
	// Step 1: Confirm device is not sealed
	status_out = gauge_control(GAUGE_CMD_CONTROL);
	status_msb = status_out >> 8;
	
	// unseal if sealed/full-accessed
	if (((status_msb & (1 << 5)) == (1<< 5)) 
		|| ((status_msb & (1 << 6)) == (1<< 6)))
	{
		unseal_flash(status_msb);
	}
	
	// Step 2: Enter ROM Mode
	status_out = gauge_control(0x0f00);	
}

/******************************************************************************
* Executes given gauge programming command and returns 0 if successful.
*
* @param *cmd	pointer to command array without start byte
******************************************************************************/
uint8_t gauge_program()
{
	uint8_t num_cmds = 0; // read once from gauge image and governs # of times for loop runs
	uint16_t ind = 0; // keeps track of index within gauge array as we step through each command
	uint8_t cmd_len = 0; // read from gauge image for each command to determine how much to increment ind by
	uint8_t gauge_error = 0; // flag that is set if any error occurs and stays set for return value
	uint8_t single_cmd[104] = {0}; // holds single command read from gauge image
	
	// First element is total # of commands
	num_cmds = pgm_read_byte(gauge_image); // read from program space
	ind++;

	// For each command, read total # of elements (includes length and code) then execute (i.e. write to gauge via I2C)
	for (int cmd = 0; cmd < num_cmds; cmd++)
	{
		cmd_len = pgm_read_byte(gauge_image + ind);
		for (int cmd_byte = 0; cmd_byte < cmd_len; cmd_byte++)
		{
			single_cmd[cmd_byte]  = pgm_read_byte(gauge_image + ind + cmd_byte);
		}
		
		gauge_error |= gauge_execute_cmd(single_cmd);
		ind = ind + cmd_len;
		
		// every 10 commands, send ACK to LabVIEW
		if (cmd % 10 == 0)
		{
			TransmitByte(0x7E);
		}
	}
	
	return gauge_error;
}

/******************************************************************************
* Executes given gauge programming command and returns 0 if successful.
*
* @param *cmd	pointer to command array without start byte
******************************************************************************/
uint8_t gauge_execute_cmd(uint8_t *cmd)
{
	uint8_t len = *cmd;
	uint8_t i2c_addr = 0;
	uint8_t reg = 0;
	uint16_t wait_time = 0;
	uint16_t wait_time2 = 0;
	uint8_t read_bytes[4];
	
	uint8_t compare_error = 0;
	
	cmd++; // advance to command type byte
	switch (*cmd)
	{
		case 'W':
			cmd++;
			i2c_addr = *cmd;
			cmd++;
			reg = *cmd;	
			cmd++;
			
			compare_error = write_array(i2c_addr, reg, cmd, (len - 4)); // -4 bc len includes len, cmd, addr, reg,
			
			break;
		
		case 'C':
			cmd++;
			i2c_addr = *cmd;
			cmd++;
			reg = *cmd;
			cmd++;
			
			(void)read_array(i2c_addr, reg, read_bytes, (len - 4));
			for (int i = 0; i < (len - 6); i++)
			{
				compare_error |= ((*(read_bytes + i)) != (*(cmd + i)));	
			}
			
			break;
		
		case 'X':
		
			// compile wait time (4 bytes, MSB first)
			wait_time2 = ((uint16_t)*(cmd + 1) << 8) | ((uint16_t)*(cmd + 2));
			wait_time = wait_time2;
			_delay_ms(wait_time);
			
			break;
	}
	
	return compare_error;
}

/******************************************************************************
* Writes control command and given sub command to fuel gauge. Returns output of
* read from control status register after update.
*
*   Called by gauge_hibernate().
*
*   @param nSubCmd  hex value corresponding to sub command
******************************************************************************/
uint16_t gauge_control(uint16_t nSubCmd)
{
	uint16_t nResult = 0;
	unsigned char pData[2] = {0x00, 0x00};

	pData[0] = nSubCmd & 0xFF;
	pData[1] = (nSubCmd >> 8) & 0xFF;

	(void)write_array(GAUGE_ADDR,GAUGE_CMD_CONTROL, pData, 2); // issue control (0x00) and sub command
	_delay_ms(100);
	(void)read_array(GAUGE_ADDR, GAUGE_CMD_CONTROL, pData, 2); // read data
	
	nResult = (pData[1] <<8) | pData[0]; //pdata[0] = low byte; pdata[1] = high byte

	return nResult;
}


/******************************************************************************
* Read unseal or full access key and write to gauge depending on status.
* Called by gauge_program_start()
*
*   @param status_msb     MSB of status read from fuel gauge
******************************************************************************/
void unseal_flash(uint8_t status_msb)
{
	// Flash read - for Unseal keys
	uint8_t seal_keys[GAUGE_CODES_LENGTH] = {0,0,0,0,0,0,0,0};    // create buffer to hold read from flash
	uint8_t one_key[4] = {0,0,0,0}; // buffer to store a subset of seal_keys with either unseal or full access only
	uint8_t classBlock[1] = {GAUGE_CODES_CLASS};
	uint8_t read_fail = 0;
	bool keys_read = false;
	
	// sealed --> unseal key
	if ((status_msb & (1 << 5)) == (1<< 5))
	{
		// read key
		(void)write_array(GAUGE_ADDR, GAUGE_CMD_CLASS, classBlock, 1); // write subclass and block # to access flash
		read_fail = read_array(GAUGE_ADDR, GAUGE_CMD_START_BLOCK, seal_keys, GAUGE_CODES_LENGTH); // read both keys
		
		// send key in reverse byte order
		for (int i = 0; i < 4; i++)
		{
			one_key[i] = *(seal_keys + 3 - i);
		}
		(void)write_array(GAUGE_ADDR,GAUGE_CMD_CONTROL, one_key, 4); // issue control (0x00) and sub command
		keys_read = true;
	}
	
	// full access seal --> full access unseal key
	if ((status_msb & (1 << 6)) == (1<< 6))
	{
		// read key if not already
		if (!keys_read)
		{
			(void)write_array(GAUGE_ADDR, GAUGE_CMD_CLASS, classBlock, 1); // write subclass and block # to access flash
			read_fail = read_array(GAUGE_ADDR, GAUGE_CMD_START_BLOCK, seal_keys, GAUGE_CODES_LENGTH); // read both keys
		}
		
		// send key in reverse byte order
		for (int i = 0; i < 4; i++)
		{
			one_key[i] = *(seal_keys + 7 - i);
		}
		(void)write_array(GAUGE_ADDR,GAUGE_CMD_CONTROL, one_key, 4); // issue control (0x00) and sub command
	}
}

/******************************************************************************\
 * Basic I2C communication functions
\******************************************************************************/

/******************************************************************************
* Reads nLength bytes from gauge and stores reading in buffer. Returns 0 when
* all operations were successful; non-zero otherwise.
*
*   Called by battery_update(), gauge_control(), and gauge_set_pfc_mode().
*
*   @param addr     i2c device address
*   @param cmd      first register (i.e. standard command) to read from
*   @param *pData   pointer to a data buffer (array)
*   @param nLength  number of bytes to read
******************************************************************************/
uint8_t read_array(unsigned char addr, unsigned char cmd, unsigned char *pData, unsigned char nLength)
{
	uint8_t errorOut = 0;
	
	// start comm with device
	errorOut = i2c_start(addr, I2C_WRITE); // returns 0 if device accessible
	
	if (!errorOut)
	{
		errorOut |= i2c_write(cmd); // returns 0 if write successful
		i2c_stop();
		_delay_us(66);						   // bus free time between start and stop conditions per LTC4162 datasheet
		errorOut |= i2c_start(addr, I2C_READ); // returns 0 if device accessible
		(void)i2c_read_many(pData, nLength, true);
		i2c_stop();
	}
	else
	{
		i2c_stop();
	}
	_delay_us(66); // Per bq27510g3 datasheet need 66us delay between packets sent to fuel gauge. 5us for 100khz, 70us for 400khz
	
	return errorOut;
}

/******************************************************************************
* Writes packet of bytes. Returns 0 if write was successful.
*
*   Called by gauge_control() and gauge_set_pfc_mode().
*
*   @param addr     i2c device address
*   @param reg      command register
*   @param *pData   pointer to a data buffer storing bytes to write to register
*   @param nLength  number of bytes to write
******************************************************************************/
uint8_t write_array(unsigned char addr, unsigned char reg, unsigned char *pData, unsigned char nLength)
{
	uint8_t errorOut = 0;
	unsigned char combined_cmd[nLength + 1];

	combined_cmd[0] = reg;
	for (int i = 0; i < nLength; i++)
	{
		combined_cmd[i+1] = *(pData + i);
	}

	(void)i2c_start(addr, I2C_WRITE); // write to fuel gauge
	errorOut = i2c_write_array(combined_cmd, (nLength + 1));
	i2c_stop();                  // stop transmitting

	_delay_us(66); // Per bq27510g3 datasheet need 66us delay between packets sent to fuel gauge
	return errorOut;
}


/************************************************************************************************************************************************************

/* I2C clock in Hz */
#ifndef I2C_SCL_CLOCK
#define I2C_SCL_CLOCK  90000L
#endif

#define F_CPU 16000000

#define I2C_WAIT_CLEAR(v, b)  while(!((v) & (1 << (b))))
#define I2C_WAIT_SET(v, b)    while((v) & (1 << (b)))

#define I2C_ENABLE_ISR()      TWCR |= (1 << TWIE)
#define I2C_DISABLE_ISR()     TWCR &= ~(1 << TWIE)

volatile i2c_t i2c_global;

/******************************************************************************
 * Handles I2C interrupt to both transmit and receive data.
 ******************************************************************************/
ISR(TWI_vect)
{
  uint8_t status;
  i2c_mode_t last_mode;

  last_mode = i2c_global.mode;
  status = TW_STATUS;

  /*
   * Receiving any of these statuses changes the current I2C mode regardless
   * of its current state.
   */
  switch(status)
  {
	  case TW_ST_SLA_ACK:
	  case TW_ST_ARB_LOST_SLA_ACK:
		i2c_global.mode = I2C_MODE_ST;
		break;
		
	  case TW_SR_SLA_ACK:
	  case TW_SR_ARB_LOST_SLA_ACK:
	  case TW_SR_GCALL_ACK:
	  case TW_SR_ARB_LOST_GCALL_ACK:
		i2c_global.mode = I2C_MODE_SR;
		break;
		
	  case TW_SR_STOP:
		TWCR |= (1 << TWEN) | (1 << TWIE) | (1 << TWINT) | (1 << TWEA);
		i2c_global.mode = I2C_MODE_IDLE;
		break;
		
	  case TW_NO_INFO:
	  case TW_BUS_ERROR:
	  TWCR = (1 << TWEN) |(1 << TWIE) | (1 << TWINT) | (1 << TWEA);
	  i2c_global.mode = I2C_MODE_IDLE;
	  break;
  }

  switch(i2c_global.mode)
  {
	  case I2C_MODE_MT:
	  case I2C_MODE_MR:
		break;
	  
	  case I2C_MODE_ST:
		if(i2c_global.st_callback)
		{
			(*i2c_global.st_callback)(status, last_mode, i2c_global.mode);
			TWCR = (1 << TWEN) | (1 << TWIE) | (1 << TWINT) | (1 << TWEA);
		}
		break;
	  case I2C_MODE_SR:
		if(i2c_global.sr_callback)
		{
			if(0 == (*i2c_global.sr_callback)(status, last_mode, i2c_global.mode))
				TWCR = (1 << TWEN) | (1 << TWIE) | (1 << TWINT) | (1 << TWEA);
		}
		break;
	  case I2C_MODE_IDLE:
		if(last_mode == I2C_MODE_SR)
		{
			if(i2c_global.stop_callback)
			{
				(*i2c_global.stop_callback)(status, last_mode, i2c_global.mode);
			}
		}
		break;
	  case I2C_MODE_UNKNOWN:
	  default:
		break;
  }
}

/******************************************************************************
 * Initializes I2C bus interface.
 ******************************************************************************/
void i2c_init(void)
{
 // setGpioPinHigh(I2C_SDA_PIN);
 // setGpioPinHigh(I2C_SCL_PIN);
  //setGpioPinModeInputPullup(I2C_SDA_PIN); // activate pullup on SDA and SCL pins 
  //setGpioPinModeInputPullup(I2C_SCL_PIN);
  
  TWSR &= ~((1 << TWPS0) & (1<<TWPS1)); // clear prescaler bits
  TWBR = ((F_CPU/I2C_SCL_CLOCK)-16)/2; // set bit rate
  
  i2c_global.mode = I2C_MODE_IDLE;
  i2c_global.st_callback = NULL;
  i2c_global.sr_callback = NULL;
  I2C_ENABLE_ISR();
}

/******************************************************************************
 * Issues a start condition and sends address and transfer direction.
 * Returns 0 if device accessible. 1 if failed to access device.
 *
 * @param address	device's I2C address
 * @param mode		byte indicating read or write mode
 ******************************************************************************/
uint8_t i2c_start(uint8_t address, uint8_t mode)
{
  uint8_t twst;

  i2c_global.mode = (mode == I2C_WRITE)?I2C_MODE_MT:I2C_MODE_MR;

  /* Send START condition */
  TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTA);

  /* Wait until transmission completed */
  I2C_WAIT_CLEAR(TWCR, TWINT);

  /* Check value of TWI Status Register. */
  twst = TW_STATUS;
  if ( (twst != TW_START) && (twst != TW_REP_START)) return twst;

  /* Send device address */
  TWDR = address | mode;
  TWCR = (1 << TWINT) | (1 << TWEN);

  /* Wait until transmission completed and ACK/NACK has been received */
  I2C_WAIT_CLEAR(TWCR, TWINT);

  /* Check value of TWI Status Register. */
  twst = TW_STATUS;
  if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return twst;

  return 0;
}

/******************************************************************************
 * Issues a repeated start condition and sends address and transfer direction.
 * Returns 0 if device accessible. 1 if failed to access device.
 *
 * @param address	device's I2C address
 * @param mode		byte indicating transfer direction (read or write)
 ******************************************************************************/
uint8_t i2c_rep_start(uint8_t address, uint8_t mode)
{
  return i2c_start(address, mode);
}



/******************************************************************************
 * Terminates the data transfer and releases the I2C bus.
 ******************************************************************************/
void i2c_stop(void)
{
  /* Send STOP condition. */
  TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);

  /* Wait until STOP condition is executed and bus released. */
  I2C_WAIT_SET(TWCR, TWSTO);

  i2c_global.mode = I2C_MODE_IDLE;
  I2C_ENABLE_ISR();
}

/******************************************************************************
 * Send one byte to I2C device.
 * Returns 0 if write successful. 1 if failed to write.
 *
 * @param data	byte to be transferred
 ******************************************************************************/
uint8_t i2c_write(uint8_t data)
{
  uint8_t twst;
 
  /* Send data to the previously addressed device */
  TWDR = data;
  TWCR = (1 << TWINT) | (1 << TWEN);

  /* Wait until transmission completed */
  I2C_WAIT_CLEAR(TWCR, TWINT);

  /* Check value of TWI Status Register. */
  twst = TW_STATUS;
  if(twst != TW_MT_DATA_ACK)
    return twst;

  return 0;
}


/******************************************************************************
 * Send an array of bytes to I2C device.
 * Returns 0 if write successful. 1 if failed to write.
 *
 * @param *data		pointer to array to be transferred
 * @param count		number of bytes to be transferred 
 ******************************************************************************/
uint8_t i2c_write_array(uint8_t *data, uint8_t count)
{
  while(count--)
  {
    if(i2c_write(*data++) != 0) return count;
  }

  return 0;
}

/******************************************************************************
 * Read one byte from the I2C device, request more data from device.
 * Returns byte read from I2c device.
 ******************************************************************************/
uint8_t i2c_read_ack(void)
{
  TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA);
  I2C_WAIT_CLEAR(TWCR, TWINT);

  return TWDR;
}


/******************************************************************************
 * Read one byte from the I2C device, read is followed by a STOP condition
 * Returns byte read from I2C device
 ******************************************************************************/
uint8_t i2c_read_nak(void)
{
  TWCR = (1 << TWINT) | (1 << TWEN);
  I2C_WAIT_CLEAR(TWCR, TWINT);

  return TWDR;
}


/******************************************************************************
 * Read multiple bytes then follow with a STOP condition if nak_last is true.
 * Returns 0.
 *
 * @param *buffer	pointer to buffer storing data to be read
 * @param count		number of bytes to read 
 * @param nak_last	flag indicating if last read byte should be followed by STOP
 ******************************************************************************/
uint8_t i2c_read_many(uint8_t *buffer, uint8_t count, uint8_t nak_last)
{
  while(count--)
  {
    *buffer++ = i2c_read(!(nak_last && (count==0)));
  }

  return 0;
}
171,7,87,22,0,3,0,0,6,87,22,100,3,0,4,88,0,20,5,67,22,102,0,104,87,22,0,2,0,0,0,234,255,51,250,250,51,181,251,51,149,254,51,173,254,51,255,255,63,255,255,63,255,255,63,255,255,63,255,255,63,255,255,63,255,255,63,255,255,63,255,255,63,255,255,63,255,255,63,1,2,63,88,203,51,195,160,8,25,0,0,0,0,0,255,170,14,251,167,14,255,166,14,255,161,14,255,160,14,254,163,14,83,162,14,222,255,58,103,255,58,226,255,51,255,175,14,6,87,22,100,53,56,4,88,0,2,5,67,22,102,0,104,87,22,0,2,1,0,0,1,79,3,63,17,12,217,255,48,224,255,53,47,16,12,224,255,53,255,255,35,227,175,4,226,191,4,209,255,54,226,160,4,227,161,4,0,199,2,1,198,2,229,175,4,227,191,1,228,175,4,226,191,1,255,172,14,225,28,4,138,255,49,226,160,4,227,161,4,2,171,24,127,43,14,255,27,14,191,255,50,252,250,14,251,175,12,2,43,24,255,27,14,152,255,54,6,87,22,100,174,44,4,88,0,2,5,67,22,102,0,5,87,22,0,5,6,87,22,100,5,0,4,88,0,170,5,67,22,102,0,8,67,22,4,239,214,106,214,10,87,22,0,12,0,0,0,131,222,6,87,22,100,109,1,4,88,0,200,5,67,22,102,0,40,87,22,0,10,0,0,0,127,113,233,8,148,9,158,190,250,126,246,0,246,0,18,72,81,246,201,244,20,82,9,33,50,109,0,0,0,0,208,126,6,87,22,100,35,13,4,88,0,2,5,67,22,102,0,40,87,22,0,10,1,0,0,23,223,0,0,23,243,0,0,58,54,253,145,0,37,48,1,0,239,5,17,5,1,0,0,16,1,0,60,0,80,60,0,6,87,22,100,67,6,4,88,0,2,5,67,22,102,0,40,87,22,0,10,2,0,0,100,60,0,32,10,20,0,2,5,16,90,254,213,251,149,0,2,0,20,3,232,1,0,1,244,0,30,0,60,14,16,0,6,87,22,100,45,7,4,88,0,2,5,67,22,102,0,40,87,22,0,10,3,0,0,10,70,5,50,1,15,1,244,0,100,70,80,10,14,47,13,241,1,144,0,100,25,0,1,0,20,0,1,0,20,3,35,6,87,22,100,54,5,4,88,0,2,5,67,22,102,0,40,87,22,0,10,4,0,0,7,8,37,90,50,15,100,96,0,160,10,190,0,200,40,1,244,0,0,0,0,0,0,0,0,0,0,67,128,4,0,0,6,87,22,100,181,5,4,88,0,2,5,67,22,102,0,40,87,22,0,10,5,0,0,15,0,42,4,10,125,0,0,1,10,254,118,231,84,0,40,3,232,2,1,44,240,0,19,82,16,98,16,56,16,15,15,6,87,22,100,12,7,4,88,0,2,5,67,22,102,0,40,87,22,0,10,6,0,0,238,15,205,15,174,15,143,15,114,15,85,15,58,15,30,15,3,14,235,14,212,14,190,14,169,14,148,14,127,14,103,14,6,87,22,100,178,9,4,88,0,2,5,67,22,102,0,40,87,22,0,10,7,0,0,83,14,64,14,49,14,42,14,32,14,26,14,19,14,12,14,5,14,2,13,250,13,243,13,221,13,199,13,162,13,133,13,6,87,22,100,240,6,4,88,0,2,5,67,22,102,0,40,87,22,0,10,8,0,0,119,13,108,13,77,12,222,10,222,251,136,252,120,253,76,253,154,253,134,253,163,253,220,254,60,254,132,254,33,254,205,254,6,87,22,100,165,20,4,88,0,2,5,67,22,102,0,40,87,22,0,10,9,0,0,201,254,188,254,49,254,236,255,80,1,47,2,244,2,75,1,119,2,32,1,248,2,72,2,174,2,235,2,179,3,48,2,6,87,22,100,213,12,4,88,0,2,5,67,22,102,0,40,87,22,0,10,10,0,0,158,255,227,254,226,253,23,252,228,253,0,254,85,255,165,0,37,255,152,254,214,242,215,172,34,255,181,255,172,255,159,255,6,87,22,100,127,23,4,88,0,2,5,67,22,102,0,40,87,22,0,10,11,0,0,117,255,191,255,184,255,194,255,140,255,177,255,180,255,157,255,144,255,67,254,165,255,107,255,60,255,60,255,29,254,209,254,6,87,22,100,135,24,4,88,0,2,5,67,22,102,0,40,87,22,0,10,12,0,0,77,255,66,255,66,254,216,254,148,254,29,253,229,254,22,254,166,255,149,252,248,0,0,1,194,0,50,255,206,2,38,100,6,87,22,100,216,18,4,88,0,2,5,67,22,102,0,40,87,22,0,10,13,0,0,123,32,0,0,96,126,0,0,0,0,100,0,25,0,100,40,99,95,100,98,0,100,0,30,0,180,0,100,0,240,0,250,6,87,22,100,165,7,4,88,0,2,5,67,22,102,0,40,87,22,0,10,14,0,0,17,16,16,104,9,217,175,55,0,0,0,2,0,20,0,0,10,240,0,10,5,0,50,1,194,20,20,0,0,60,0,75,6,87,22,100,60,5,4,88,0,2,5,67,22,102,0,40,87,22,0,10,15,0,0,0,40,0,60,60,1,144,54,114,4,20,255,255,255,255,1,35,69,103,137,171,205,239,254,220,186,152,118,84,50,16,0,6,87,22,100,254,13,4,88,0,2,5,67,22,102,0,40,87,22,0,10,16,0,0,1,44,0,200,7,231,253,216,55,224,0,175,0,180,10,100,1,0,60,0,0,0,0,0,0,0,0,0,0,0,0,0,6,87,22,100,247,6,4,88,0,2,5,67,22,102,0,40,87,22,0,10,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,87,22,100,27,0,4,88,0,2,5,67,22,102,0,40,87,22,0,10,18,0,0,2,38,2,1,244,2,88,2,2,38,14,0,0,0,0,0,0,0,0,0,0,0,0,13,0,214,64,43,68,115,175,14,6,87,22,100,143,4,4,88,0,2,5,67,22,102,0,40,87,22,0,10,19,0,0,16,0,0,0,1,0,6,3,132,100,3,232,21,24,254,112,16,104,16,104,16,4,10,50,30,0,10,45,55,1,1,1,6,87,22,100,116,5,4,88,0,2,5,67,22,102,0,40,87,22,0,10,20,0,0,11,98,113,51,52,122,49,48,48,45,71,49,11,84,101,120,97,115,32,73,110,115,116,46,4,76,73,79,78,0,150,0,6,87,22,100,219,8,4,88,0,2,5,67,22,102,0,40,87,22,0,10,21,0,0,175,0,75,0,100,10,240,2,11,84,16,204,2,16,104,100,1,3,5,0,0,0,0,0,0,0,0,0,0,0,0,0,6,87,22,100,155,4,4,88,0,2,5,67,22,102,0,40,87,22,0,10,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,6,87,22,100,19,13,4,88,0,2,5,67,22,102,0,40,87,22,0,10,23,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,6,87,22,100,1,32,4,88,0,2,5,67,22,102,0,40,87,22,0,10,24,0,0,255,85,0,82,0,91,0,107,0,144,0,164,0,90,0,112,0,116,0,100,0,99,0,112,0,136,0,237,2,76,6,116,6,87,22,100,116,8,4,88,0,2,5,67,22,102,0,40,87,22,0,10,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,87,22,100,35,0,4,88,0,2,5,67,22,102,0,40,87,22,0,10,26,0,0,255,255,0,82,0,91,0,107,0,144,0,164,0,90,0,112,0,116,0,100,0,99,0,112,0,136,0,237,2,76,6,116,6,87,22,100,32,9,4,88,0,2,5,67,22,102,0,40,87,22,0,10,27,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,87,22,100,37,0,4,88,0,2,5,67,22,102,0,40,87,22,0,10,28,0,0,17,16,16,104,9,217,175,55,0,0,0,2,0,20,0,0,10,240,0,10,5,0,50,1,194,20,20,0,0,60,0,75,6,87,22,100,74,5,4,88,0,2,5,67,22,102,0,40,87,22,0,10,29,0,0,0,40,0,60,60,1,144,54,114,4,20,255,255,255,255,1,35,69,103,137,171,205,239,254,220,186,152,118,84,50,16,0,6,87,22,100,12,14,4,88,0,2,5,67,22,102,0,40,87,22,0,10,30,0,0,255,255,255,255,0,0,4,149,255,255,251,105,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,6,87,22,100,11,28,4,88,0,2,5,67,22,102,0,40,87,22,0,10,31,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,6,87,22,100,9,32,4,88,0,2,5,67,22,102,0,5,87,22,0,8,6,87,22,100,8,0,4,88,0,2,5,67,22,102,0,6,67,22,4,24,102,5,87,22,0,5,6,87,22,100,5,0,4,88,0,170,5,67,22,102,0,8,67,22,4,239,214,106,214,11,87,22,0,1,0,0,5,84,84,21,6,87,22,100,195,0,4,88,0,20,5,67,22,102,0,5,87,22,0,5,6,87,22,100,5,0,4,88,0,170,5,67,22,102,0,8,67,22,4,68,43,64,214,5,87,22,0,15,6,87,22,100,15,0,4,88,15,160,

  • Hello Patricia,

    If bqStudio is programming it correctly, then i would suspect error handling in the MCU code.

    An easy way to check is to compare the communication traffic between bqStudio and MCU code for the same DFFS file