Part Number:BQ76PL455A-Q1
Dear Sir,
I am working on BQ76PL455A-Q1 for EV BMS application. In the circuit 2 IC's of BQ76PL455A-Q1 are used.
First i checked with BQSTUDIO GUI :--> Both the IC's got detected and I could read all the voltages.
Now when I use microcontroller for programming the same, I am able to read Bottom device but unable to read the Top device.
Texas API are used for programming (As per Example code)
Please verify my attached code below.
void WakePL455(void)
{
#ifdef CONF_BQ76PL455
// Wake all devices
// The wake tone will awaken any device that is already in shutdown and the pwrdown will shutdown any device
// that is already awake. The least number of times to sequence wake and pwrdown will be half the number of
// boards to cover the worst case combination of boards already awake or shutdown.
// toggle wake signal
ioport_set_pin_level(Wakeup, false);
delay_ms(5);
ioport_set_pin_level(Wakeup, true);
delay_ms(5);
ioport_set_pin_level(Wakeup, false);
#endif
}
void auto_address()
{
/*
Summary of Steps for Auto-Addressing
1. Make sure all boards are awake and ready to receive the AUTO-ADDRESS ENABLE command.
2. Turn on the downstream communications drivers on all devices in the chain.
3. Place all devices into auto-address learn mode.
4. Send out new addresses to all possible bq76PL455A-Q1 device addresses, in incremental order,
starting at 0.
5. Read back the value stored in the Device Address register from each newly addressed device, starting
at address 0 and proceeding sequentially. The last bq76PL455A-Q1 device to successfully respond is
the last device in the serial chain.
6. Turn off the high-side communications receiver on the last (top-most) device in the chain.
7. Turn off the single-ended transmitter on all except the lowest device in the chain.
*/
// set communications baud rate as 250KBaud
nDev_ID = 0;
nSent = WriteReg(nDev_ID, COMCONFIG, 0x10E0, 2, FRMWRT_ALL_NR);
// Address will be set using Auto Addressing.
// Comparator hysteresis is disabled.
// Over voltage (OV) and under voltage (UV) comparators are enabled.
// Internal regulator (NPN drive for VP/VDIG) is enabled. This is the normal operating mode.
// Faults are unlatched and clear automatically,
nSent = WriteReg(nDev_ID, DEVCONFIG, 0x10, 1, FRMWRT_ALL_NR);
// Auto Address enable
nSent = WriteReg(nDev_ID, DEV_CTRL, 0x08, 1, FRMWRT_ALL_NR);
// Set addresses for all boards in daisy-chain (section 1.2.3)
for (nDev_ID = 0; nDev_ID < TOTALBOARDS; nDev_ID++)
{
nSent = WriteReg(nDev_ID, ADDR, nDev_ID, 1, FRMWRT_ALL_NR); // send address to each board
}
// enable only comm-low for the top board
nDev_ID = 1;
nSent = WriteReg(nDev_ID, COMCONFIG, 0x1020, 2, FRMWRT_SGL_NR);
// enable comm-high, single-end comm port on bottom board
nDev_ID = 0;
nSent = WriteReg(nDev_ID, COMCONFIG, 0x10C0, 2, FRMWRT_SGL_NR);
// clear all fault summary flags
nDev_ID = 1;
nSent = WriteReg(0, FAULT_SUM, 0xFFC0, 2, FRMWRT_SGL_NR);
nDev_ID = 0;
nSent = WriteReg(0, FAULT_SUM, 0xFFC0, 2, FRMWRT_SGL_NR);
}
void configure_AFE(void)
{
nDev_ID = 1;
nSent = WriteReg(nDev_ID, SMPL_DLY1, 0x00, 1, FRMWRT_SGL_NR); // initial sampling delay
nSent = WriteReg(nDev_ID, CELL_SPER, 0xBC, 1, FRMWRT_SGL_NR); // voltage and Temp sampling interval 12.6us
//nSent = WriteReg(nDev_ID, AUX_SPER, 0x44444444, 4, FRMWRT_SGL_NR); // initial sampling delay
nSent = WriteReg(nDev_ID, OVERSMPL, 0x00, 1, FRMWRT_SGL_NR); // Oversampling rate and command
nSent = WriteReg(nDev_ID, DEV_STATUS, 0x38, 1, FRMWRT_SGL_NR); // clear fault flags in the system status register
nSent = WriteReg(nDev_ID, FAULT_SUM, 0xFFC0, 2, FRMWRT_SGL_NR); // clear all fault summary flags
nSent = WriteReg(nDev_ID, NCHAN, 0x0D, 1, FRMWRT_SGL_NR); // NCHAN : set number of cells to 13
nSent = WriteReg(nDev_ID, CHANNELS, 0x1FFF0000, 4, FRMWRT_SGL_NR); // select all 14 cell, AUX channels 6 AND 8, and internal digital die and internal analog die temperatures
nDev_ID = 0;
nSent = WriteReg(nDev_ID, SMPL_DLY1, 0x00, 1, FRMWRT_SGL_NR); // initial sampling delay
nSent = WriteReg(nDev_ID, CELL_SPER, 0x44, 1, FRMWRT_SGL_NR); // voltage and Temp sampling interval 12.6us
nSent = WriteReg(nDev_ID, AUX_SPER, 0x44444444, 4, FRMWRT_SGL_NR); // initial sampling delay
nSent = WriteReg(nDev_ID, OVERSMPL, 0x00, 1, FRMWRT_SGL_NR); // Oversampling rate and command
nSent = WriteReg(nDev_ID, DEV_STATUS, 0x38, 1, FRMWRT_SGL_NR); // clear fault flags in the system status register
nSent = WriteReg(nDev_ID, FAULT_SUM, 0xFFC0, 2, FRMWRT_SGL_NR); // clear all fault summary flags
nSent = WriteReg(nDev_ID, NCHAN, 0x0E, 1, FRMWRT_SGL_NR); // NCHAN : set number of cells to 14
nSent = WriteReg(nDev_ID, CHANNELS, 0x3FFF0000, 4, FRMWRT_SGL_NR); // select all 14 cell, AUX channels 6 AND 8, and internal digital die and internal analog die temperatures
Voltage_threshold(); // Cell OV,UV,Comp_OV, Comp_UV voltage threshold setting
Thermistor_threshold(); // Auxiliary thermistors Upper and Lower limit threshold setting
}
void Voltage_threshold(void)
{
uint16_t OV_thresh, UV_thresh;
uint8_t OVC_thresh, UVC_thresh;
Volt_th(OV_th, UV_th, &OV_thresh, &UV_thresh);
Comp_volt_th(COV_th, CUV_th, &OVC_thresh, &UVC_thresh);
nDev_ID = 0;
nSent = WriteReg(nDev_ID, CELL_OV, OV_thresh, 2, FRMWRT_ALL_NR); // Cell overvoltage threshold
nSent = WriteReg(nDev_ID, CELL_UV, UV_thresh, 2, FRMWRT_ALL_NR); // Cell undervoltage threshold
nSent = WriteReg(nDev_ID, COMP_OV, OVC_thresh, 1, FRMWRT_ALL_NR); // Cell comparator overvoltage threshold
nSent = WriteReg(nDev_ID, COMP_UV, UVC_thresh, 1, FRMWRT_ALL_NR); // Cell comparator undervoltage threshold
}
void Thermistor_threshold(void)
{
uint32_t UT_thresh, OT_thresh;
Temperature_th(UT_th, OT_th, &UT_thresh, &OT_thresh);
nDev_ID = 0;
nSent = WriteReg(nDev_ID, AUX0_UV, UT_thresh, 2, FRMWRT_ALL_NR); // Auxillary 0 undervoltage threshold
nSent = WriteReg(nDev_ID, AUX0_OV, OT_thresh, 2, FRMWRT_ALL_NR); // Auxillary 0 overvoltage threshold
nSent = WriteReg(nDev_ID, AUX1_UV, UT_thresh, 2, FRMWRT_ALL_NR); // Auxillary 1 undervoltage threshold
nSent = WriteReg(nDev_ID, AUX1_OV, OT_thresh, 2, FRMWRT_ALL_NR); // Auxillary 1 overvoltage threshold
nSent = WriteReg(nDev_ID, AUX2_UV, UT_thresh, 2, FRMWRT_ALL_NR); // Auxillary 2 undervoltage threshold
nSent = WriteReg(nDev_ID, AUX2_OV, OT_thresh, 2, FRMWRT_ALL_NR); // Auxillary 2 overvoltage threshold
nSent = WriteReg(nDev_ID, AUX3_UV, UT_thresh, 2, FRMWRT_ALL_NR); // Auxillary 3 undervoltage threshold
nSent = WriteReg(nDev_ID, AUX3_OV, OT_thresh, 2, FRMWRT_ALL_NR); // Auxillary 3 overvoltage threshold
nSent = WriteReg(nDev_ID, AUX4_UV, UT_thresh, 2, FRMWRT_ALL_NR); // Auxillary 4 undervoltage threshold
nSent = WriteReg(nDev_ID, AUX4_OV, OT_thresh, 2, FRMWRT_ALL_NR); // Auxillary 4 overvoltage threshold
nSent = WriteReg(nDev_ID, AUX5_UV, UT_thresh, 2, FRMWRT_ALL_NR); // Auxillary 5 undervoltage threshold
nSent = WriteReg(nDev_ID, AUX5_OV, OT_thresh, 2, FRMWRT_ALL_NR); // Auxillary 5 overvoltage threshold
nSent = WriteReg(nDev_ID, AUX6_UV, UT_thresh, 2, FRMWRT_ALL_NR); // Auxiliary 6 undervoltage threshold
nSent = WriteReg(nDev_ID, AUX6_OV, OT_thresh, 2, FRMWRT_ALL_NR); // Auxillary 6 overvoltage threshold
nSent = WriteReg(nDev_ID, AUX7_UV, UT_thresh, 2, FRMWRT_ALL_NR); // Auxillary 7 undervoltage threshold
nSent = WriteReg(nDev_ID, AUX7_OV, OT_thresh, 2, FRMWRT_ALL_NR); // Auxillary 7 overvoltage threshold
}
void power_config(void)
{
/*
AFE_PCTL = 1 It is strongly recommended this bit be set to 1.
Cell voltage sampling will be delayed by 100 µs every time sampling is requested, regardless of whether
or not the AFE was already powered up. This provides time for the AFE to power up and ensures that
the sampling synchronization is maintained between multiple devices.
Changes to this register may not take effect until after the next AFE sample is taken
RSVD = 0000000
BYTE = 10000000 BINARY = 0X80 HEX
*/
nDev_ID = 0;
nSent = WriteReg(nDev_ID, PWRCONFIG, 0x80, 1, FRMWRT_ALL_NR); // standard configuration as per data sheet
}
void bq76pl455_init(void)
{
auto_address();
power_config(); // Power configuration as per data sheet
configure_AFE();
}
void readvoltage(void)
{
// Send request to All boards to sample and store results
nDev_ID = 0;
nSent = WriteReg(nDev_ID, CMD, 0x00, 1, FRMWRT_ALL_NR); // send sync sample and store command
delay_us(2800); // still need to wait for sampling to complete
// Read stored sample data from boards
nDev_ID = 1;
nSent = WriteReg(nDev_ID, CMD, 0x20, 1, FRMWRT_SGL_R); // send read stored values command
// Read stored sample data from boards
nDev_ID = 0;
nSent = WriteReg(nDev_ID, CMD, 0x20, 1, FRMWRT_SGL_R); // send read stored values command
}
int main (void)
{
/* Insert application code here, after the board has been initialized. */
initialization();
/* Insert system clock initialization code here (sysclk_init()). */
module_test();
readvoltage();
while(1)
{
counter();
}
}
UART is Interrupt based.
Thanks
Ritul Shah