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.

BQ79616-Q1: BQ79616 can not sent any data through it's UART

Part Number: BQ79616-Q1
Other Parts Discussed in Thread: BQ79616

Hi 

Our final design is to use the 79616, but when we bought the development board, we bought the 79656 development board.

I am currently using an MCU to communicate with 79656 through UART. It is now possible to wake up the 79656 chip, but cannot read any registers of the 79656. I have configured the MAIN ADC but cannot read any data from 79656. Below is my main code( 79616 driver).

There is only one 79656 development board in the test. Please give me a help, thank you!

Best regards,


//**********************
//AUTO ADDRESS SEQUENCE
//**********************
void AutoAddress()
{
//DUMMY WRITE TO SNCHRONIZE ALL DAISY CHAIN DEVICES DLL (IF A DEVICE RESET OCCURED PRIOR TO THIS)
WriteReg(0, OTP_ECC_DATAIN1, 0X00, 1, FRMWRT_ALL_W);
WriteReg(0, OTP_ECC_DATAIN2, 0X00, 1, FRMWRT_ALL_W);
WriteReg(0, OTP_ECC_DATAIN3, 0X00, 1, FRMWRT_ALL_W);
WriteReg(0, OTP_ECC_DATAIN4, 0X00, 1, FRMWRT_ALL_W);
WriteReg(0, OTP_ECC_DATAIN5, 0X00, 1, FRMWRT_ALL_W);
WriteReg(0, OTP_ECC_DATAIN6, 0X00, 1, FRMWRT_ALL_W);
WriteReg(0, OTP_ECC_DATAIN7, 0X00, 1, FRMWRT_ALL_W);
WriteReg(0, OTP_ECC_DATAIN8, 0X00, 1, FRMWRT_ALL_W);

//ENABLE AUTO ADDRESSING MODE
WriteReg(0, CONTROL1, 0X01, 1, FRMWRT_ALL_W);

//SET ADDRESSES FOR EVERY BOARD
for(currentBoard=0; currentBoard<TOTALBOARDS; currentBoard++)
{
WriteReg(0, DIR0_ADDR, currentBoard, 1, FRMWRT_ALL_W);
}

WriteReg(0, COMM_CTRL, 0x02, 1, FRMWRT_ALL_W); //set everything as a stack device first

if(TOTALBOARDS==1) //if there's only 1 board, it's the base AND top of stack, so change it to those
{
WriteReg(0, COMM_CTRL, 0x01, 1, FRMWRT_SGL_W);
}
else //otherwise set the base and top of stack individually
{
WriteReg(0, COMM_CTRL, 0x00, 1, FRMWRT_SGL_W);
WriteReg(TOTALBOARDS-1, COMM_CTRL, 0x03, 1, FRMWRT_SGL_W);
}

//SYNCRHONIZE THE DLL WITH A THROW-AWAY READ
ReadReg(0, OTP_ECC_DATAIN1, response_frame2, 1, 0, FRMWRT_ALL_R);
ReadReg(0, OTP_ECC_DATAIN2, response_frame2, 1, 0, FRMWRT_ALL_R);
ReadReg(0, OTP_ECC_DATAIN3, response_frame2, 1, 0, FRMWRT_ALL_R);
ReadReg(0, OTP_ECC_DATAIN4, response_frame2, 1, 0, FRMWRT_ALL_R);
ReadReg(0, OTP_ECC_DATAIN5, response_frame2, 1, 0, FRMWRT_ALL_R);
ReadReg(0, OTP_ECC_DATAIN6, response_frame2, 1, 0, FRMWRT_ALL_R);
ReadReg(0, OTP_ECC_DATAIN7, response_frame2, 1, 0, FRMWRT_ALL_R);
ReadReg(0, OTP_ECC_DATAIN8, response_frame2, 1, 0, FRMWRT_ALL_R);

/*//OPTIONAL: read back all device addresses
for(currentBoard=0; currentBoard<TOTALBOARDS; currentBoard++)
{
ReadReg(currentBoard, DIR0_ADDR, response_frame2, 1, 0, FRMWRT_SGL_R);
printf("board %d\n",response_frame2[4]);
}*/

//RESET ANY COMM FAULT CONDITIONS FROM STARTUP
WriteReg(0, FAULT_RST2, 0x03, 1, FRMWRT_ALL_W);

return;
}
//**************************
//END AUTO ADDRESS SEQUENCE
//**************************


//************************
//WRITE AND READ FUNCTIONS
//************************

//FORMAT WRITE DATA, SEND TO
//BE COMBINED WITH REST OF FRAME
int WriteReg(BYTE bID, uint16_t wAddr, uint64_t dwData, BYTE bLen, BYTE bWriteType) {
// device address, register start address, data bytes, data length, write type (single, broadcast, stack)
bRes = 0;
memset(bBuf,0,sizeof(bBuf));
switch (bLen) {
case 1:
bBuf[0] = dwData & 0x00000000000000FF;
bRes = WriteFrame(bID, wAddr, bBuf, 1, bWriteType);
break;
case 2:
bBuf[0] = (dwData & 0x000000000000FF00) >> 8;
bBuf[1] = dwData & 0x00000000000000FF;
bRes = WriteFrame(bID, wAddr, bBuf, 2, bWriteType);
break;
case 3:
bBuf[0] = (dwData & 0x0000000000FF0000) >> 16;
bBuf[1] = (dwData & 0x000000000000FF00) >> 8;
bBuf[2] = dwData & 0x00000000000000FF;
bRes = WriteFrame(bID, wAddr, bBuf, 3, bWriteType);
break;
case 4:
bBuf[0] = (dwData & 0x00000000FF000000) >> 24;
bBuf[1] = (dwData & 0x0000000000FF0000) >> 16;
bBuf[2] = (dwData & 0x000000000000FF00) >> 8;
bBuf[3] = dwData & 0x00000000000000FF;
bRes = WriteFrame(bID, wAddr, bBuf, 4, bWriteType);
break;
case 5:
bBuf[0] = (dwData & 0x000000FF00000000) >> 32;
bBuf[1] = (dwData & 0x00000000FF000000) >> 24;
bBuf[2] = (dwData & 0x0000000000FF0000) >> 16;
bBuf[3] = (dwData & 0x000000000000FF00) >> 8;
bBuf[4] = dwData & 0x00000000000000FF;
bRes = WriteFrame(bID, wAddr, bBuf, 5, bWriteType);
break;
case 6:
bBuf[0] = (dwData & 0x0000FF0000000000) >> 40;
bBuf[1] = (dwData & 0x000000FF00000000) >> 32;
bBuf[2] = (dwData & 0x00000000FF000000) >> 24;
bBuf[3] = (dwData & 0x0000000000FF0000) >> 16;
bBuf[4] = (dwData & 0x000000000000FF00) >> 8;
bBuf[5] = dwData & 0x00000000000000FF;
bRes = WriteFrame(bID, wAddr, bBuf, 6, bWriteType);
break;
case 7:
bBuf[0] = (dwData & 0x00FF000000000000) >> 48;
bBuf[1] = (dwData & 0x0000FF0000000000) >> 40;
bBuf[2] = (dwData & 0x000000FF00000000) >> 32;
bBuf[3] = (dwData & 0x00000000FF000000) >> 24;
bBuf[4] = (dwData & 0x0000000000FF0000) >> 16;
bBuf[5] = (dwData & 0x000000000000FF00) >> 8;
bBuf[6] = dwData & 0x00000000000000FF;
bRes = WriteFrame(bID, wAddr, bBuf, 7, bWriteType);
break;
case 8:
bBuf[0] = (dwData & 0xFF00000000000000) >> 56;
bBuf[1] = (dwData & 0x00FF000000000000) >> 48;
bBuf[2] = (dwData & 0x0000FF0000000000) >> 40;
bBuf[3] = (dwData & 0x000000FF00000000) >> 32;
bBuf[4] = (dwData & 0x00000000FF000000) >> 24;
bBuf[5] = (dwData & 0x0000000000FF0000) >> 16;
bBuf[6] = (dwData & 0x000000000000FF00) >> 8;
bBuf[7] = dwData & 0x00000000000000FF;
bRes = WriteFrame(bID, wAddr, bBuf, 8, bWriteType);
break;
default:
break;
}
return bRes;
}

//GENERATE COMMAND FRAME
int WriteFrame(BYTE bID, uint16_t wAddr, BYTE * pData, BYTE bLen, BYTE bWriteType) {
int bPktLen = 0;
uint8_t * pBuf = pFrame;
memset(pFrame, 0x7F, sizeof(pFrame));
*pBuf++ = 0x80 | (bWriteType) | ((bWriteType & 0x10) ? bLen - 0x01 : 0x00); //Only include blen if it is a write; Writes are 0x90, 0xB0, 0xD0
if (bWriteType == FRMWRT_SGL_R || bWriteType == FRMWRT_SGL_W)
{
*pBuf++ = (bID & 0x00FF);
}
*pBuf++ = (wAddr & 0xFF00) >> 8;
*pBuf++ = wAddr & 0x00FF;

while (bLen--)
*pBuf++ = *pData++;

bPktLen = pBuf - pFrame;

wCRC = CRC16(pFrame, bPktLen);
*pBuf++ = wCRC & 0x00FF;
*pBuf++ = (wCRC & 0xFF00) >> 8;
bPktLen += 2;
//THIS SEEMS to occasionally drop bytes from the frame. Sometimes is not sending the last frame of the CRC.
//(Seems to be caused by stack overflow, so take precautions to reduce stack usage in function calls)
// sciSend(sciREG, bPktLen, pFrame);
// Send g_tipString out.
xfer.data = pFrame;
xfer.dataSize = bPktLen;
txOnGoing = true;
// LPUART_WriteBlocking(DEMO_LPUART, pBuf, bPktLen );
LPUART_TransferSendNonBlocking(DEMO_LPUART, &g_lpuartHandle, &xfer);
while (txOnGoing)
{
}
return bPktLen;
}

//GENERATE READ COMMAND FRAME AND THEN WAIT FOR RESPONSE DATA (INTERRUPT MODE FOR SCIRX)
int ReadReg(BYTE bID, uint16_t wAddr, uint8_t * pData, BYTE bLen, uint32_t dwTimeOut,
BYTE bWriteType) {
// device address, register start address, byte frame pointer to store data, data length, read type (single, broadcast, stack)
bRes = 0;
count = 1000000; //timeout after this many attempts

if (bWriteType == FRMWRT_SGL_R) {
ReadFrameReq(bID, wAddr, bLen, bWriteType);
memset(pData, 0, bLen + 6);

// sciEnableNotification(sciREG, SCI_RX_INT);
receiveXfer.data = pData;
receiveXfer.dataSize = bLen + 6;
if ((!rxOnGoing) && rxBufferEmpty)
{
rxOnGoing = true;
LPUART_TransferReceiveNonBlocking(DEMO_LPUART, &g_lpuartHandle, &receiveXfer, NULL);
}
// while(rxOnGoing){}

// LPUART_ReadBlocking(DEMO_LPUART, pData, bLen + 6);


// while(UART_RX_RDY == 0U && count>0) count--; /* Wait */
// UART_RX_RDY = 0;
bRes = bLen + 6;
} else if (bWriteType == FRMWRT_STK_R) {
bRes = ReadFrameReq(bID, wAddr, bLen, bWriteType);
memset(pData, 0, (bLen + 6) * (TOTALBOARDS - 1));
// sciEnableNotification(sciREG, SCI_RX_INT);
receiveXfer.data = pData;
receiveXfer.dataSize = (bLen + 6) * (TOTALBOARDS - 1);
// LPUART_ReadBlocking(DEMO_LPUART, pData, (bLen + 6) * (TOTALBOARDS - 1));
if ((!rxOnGoing) && rxBufferEmpty)
{
rxOnGoing = true;
LPUART_TransferReceiveNonBlocking(DEMO_LPUART, &g_lpuartHandle, &receiveXfer, NULL);
}
// while(rxOnGoing){}
// sciReceive(sciREG, (bLen + 6) * (TOTALBOARDS - 1), pData);
// while(UART_RX_RDY == 0U && count>0) count--; /* Wait */
// UART_RX_RDY = 0;
bRes = (bLen + 6) * (TOTALBOARDS - 1);
} else if (bWriteType == FRMWRT_ALL_R) {
bRes = ReadFrameReq(bID, wAddr, bLen, bWriteType);
memset(pData, 0, (bLen + 6) * TOTALBOARDS);
receiveXfer.data = pData;
receiveXfer.dataSize = (bLen + 6) * TOTALBOARDS;
rxOnGoing=0;
if ((!rxOnGoing) && rxBufferEmpty)
{
rxOnGoing = true;
LPUART_TransferReceiveNonBlocking(DEMO_LPUART, &g_lpuartHandle, &receiveXfer, NULL);
}
// while(rxOnGoing) {}
/* LPUART_ReadBlocking(DEMO_LPUART, pData, (bLen + 6) * TOTALBOARDS); */
// while(UART_RX_RDY == 0U && count>0) count--; /* Wait */
// UART_RX_RDY = 0;
bRes = (bLen + 6) * TOTALBOARDS;
} else {
bRes = 0;
}

// //CHECK IF CRC IS CORRECT
// for(crc_i=0; crc_i<bRes; crc_i+=(bLen+6))
// {
// if(CRC16(&pData[crc_i], bLen+6)!=0)
// {
// printf("BAD CRC\n");
// }
// }

return bRes;
}

int ReadFrameReq(BYTE bID, uint16_t wAddr, BYTE bByteToReturn, BYTE bWriteType)
{
bReturn = bByteToReturn - 1;

if (bReturn > 127)
return 0;

return WriteFrame(bID, wAddr, &bReturn, 1, bWriteType);
}

// CRC16 TABLE
// ITU_T polynomial: x^16 + x^15 + x^2 + 1
const uint16_t crc16_table[256] = { 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301,
0x03C0, 0x0280, 0xC241, 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1,
0xC481, 0x0440, 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81,
0x0E40, 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0x1E00,
0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1,
0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, 0xD201, 0x12C0, 0x1380,
0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, 0xF001, 0x30C0, 0x3180, 0xF141,
0x3300, 0xF3C1, 0xF281, 0x3240, 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501,
0x35C0, 0x3480, 0xF441, 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0,
0x3E80, 0xFE41, 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881,
0x3840, 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0xE401,
0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1,
0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, 0xA001, 0x60C0, 0x6180,
0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740,
0xA501, 0x65C0, 0x6480, 0xA441, 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01,
0x6FC0, 0x6E80, 0xAE41, 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1,
0xA881, 0x6840, 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80,
0xBA41, 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, 0x7200,
0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, 0x5000, 0x90C1,
0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, 0x9601, 0x56C0, 0x5780,
0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, 0x9C01, 0x5CC0, 0x5D80, 0x9D41,
0x5F00, 0x9FC1, 0x9E81, 0x5E40, 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901,
0x59C0, 0x5880, 0x9841, 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1,
0x8A81, 0x4A40, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80,
0x8C41, 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 };

uint16_t CRC16(BYTE *pBuf, int nLen) {
uint16_t wCRC = 0xFFFF;
int i;

for (i = 0; i < nLen; i++) {
wCRC ^= (*pBuf++) & 0x00FF;
wCRC = crc16_table[wCRC & 0x00FF] ^ (wCRC >> 8);
}

return wCRC;
}
//****************************
//END WRITE AND READ FUNCTIONS
//****************************

//************************
//MISCELLANEOUS FUNCTIONS
//************************
/*
BOOL GetFaultStat() {

if (!gioGetBit(gioPORTA, 0))
return 0;
return 1;
}
*/

void ResetAllFaults(BYTE bID, BYTE bWriteType)
{
//BROADCAST INCLUDES EXTRA FUNCTIONALITY TO OVERWRITE THE CUST_CRC WITH THE CURRENT SETTINGS
if(bWriteType==FRMWRT_ALL_W)
{
//READ THE CALCULATED CUSTOMER CRC VALUES
ReadReg(0, CUST_CRC_RSLT_HI, fault_frame, 2, 0, FRMWRT_ALL_R);
//OVERWRITE THE CRC OF EVERY BOARD IN THE STACK WITH THE CORRECT CRC
for(currentBoard=0; currentBoard<TOTALBOARDS; currentBoard++)
{
//THE RETURN FRAME STARTS WITH THE HIGHEST BOARD FIRST, SO THIS WILL WRITE THE HIGHEST BOARD FIRST
WriteReg(TOTALBOARDS-currentBoard-1, CUST_CRC_HI, fault_frame[currentBoard*8+4] << 8 | fault_frame[currentBoard*8+5], 2, FRMWRT_SGL_W);
}
//NOW CLEAR EVERY FAULT
WriteReg(0, FAULT_RST1, 0xFFFF, 2, FRMWRT_ALL_W);
}
else if(bWriteType==FRMWRT_SGL_W)
{
WriteReg(bID, FAULT_RST1, 0xFFFF, 2, FRMWRT_SGL_W);
}
else if(bWriteType==FRMWRT_STK_W)
{
WriteReg(0, FAULT_RST1, 0xFFFF, 2, FRMWRT_STK_W);
}
else
{
// printf("ERROR: ResetAllFaults bWriteType incorrect\n");
}
}

void MaskAllFaults(BYTE bID, BYTE bWriteType)
{
if(bWriteType==FRMWRT_ALL_W)
{
WriteReg(0, FAULT_MSK1, 0xFFFF, 2, FRMWRT_ALL_W);
}
else if(bWriteType==FRMWRT_SGL_W)
{
WriteReg(bID, FAULT_MSK1, 0xFFFF, 2, FRMWRT_SGL_W);
}
else if(bWriteType==FRMWRT_STK_W)
{
WriteReg(0, FAULT_MSK1, 0xFFFF, 2, FRMWRT_STK_W);
}
else
{
// printf("ERROR: MaskAllFaults bWriteType incorrect\n");
}
}

void PrintAllFaults(BYTE bID, BYTE bWriteType)
{
//PRINT 39 REGISTERS STARTING FROM FAULT_SUMMARY (INCLUDES RESERVED REGISTERS)
// printf("\n");
currentBoard = 0;
currentCell = 0;
memset(fault_frame,0,sizeof(fault_frame));
if(bWriteType==FRMWRT_ALL_R)
{
ReadReg(0, FAULT_SUMMARY, fault_frame, 39, 0, FRMWRT_ALL_R);
for(currentBoard = 0; currentBoard<TOTALBOARDS; currentBoard++)
{
// printf("BOARD %d FAULTS:\t",TOTALBOARDS-currentBoard);
for(currentCell = 0; currentCell<39; currentCell++)
{
// printf("%02x ",fault_frame[(currentBoard*(39+6))+4+currentCell]);
}
// printf("\n");
}
}
else if(bWriteType==FRMWRT_SGL_R)
{
ReadReg(bID, FAULT_SUMMARY, fault_frame, 39, 0, FRMWRT_SGL_R);
// printf("BOARD %d FAULTS:\t",bID);
for(currentCell = 0; currentCell<39; currentCell++)
{
// printf("%02x ",fault_frame[4+currentCell]);
}
// printf("\n");
}
else if(bWriteType==FRMWRT_STK_R)
{
ReadReg(0, FAULT_SUMMARY, fault_frame, 39, 0, FRMWRT_STK_R);
for(currentBoard = 0; currentBoard<(TOTALBOARDS-1); currentBoard++)
{
// printf("BOARD %d FAULTS:\t",TOTALBOARDS-currentBoard);
for(currentCell = 0; currentCell<39; currentCell++)
{
// printf("%02x ",fault_frame[(currentBoard*(39+6))+4+currentCell]);
}
// printf("\n");
}
}
else
{
// printf("ERROR: PrintAllFaults bWriteType incorrect\n");
}
// printf("\n");
}

//RUN BASIC CELL BALANCING FOR ALL DEVICES
void RunCB( uint8_t Chipaddr,uint64_t CB_16_9_CTRL,uint64_t CB_8_1_CTRL) // add chip address, CB channel ,
{
//SET BALANCING TIMERS TO 9 hours
WriteReg(Chipaddr, CB_CELL16_CTRL, CB_16_9_CTRL, 8, FRMWRT_SGL_W); //cell 16-9 (8 byte max write) FRMWRT_SGL_W 0x1F1F1F1F1F1F1F1F
WriteReg(Chipaddr, CB_CELL8_CTRL, CB_8_1_CTRL, 8, FRMWRT_SGL_W); //all cells be set to 9 hours

//SET DUTY CYCLE TO 10 s (default)
WriteReg(Chipaddr, BAL_CTRL1, 0x01, 1, FRMWRT_SGL_W); //10s duty cycle

//OPTIONAL: SET VCBDONE THRESH TO 3V, AND OVUV_GO
WriteReg(Chipaddr, VCB_DONE_THRESH, 0x08, 1, FRMWRT_SGL_W); //3V threshold (8*25mV + 2.8V)
WriteReg(Chipaddr, OVUV_CTRL, 0x05, 1, FRMWRT_SGL_W); //round-robin and OVUV_GO

//START BALANCING
WriteReg(Chipaddr, BAL_CTRL2, 0x03, 1, FRMWRT_SGL_W); //auto balance and BAL_GO
}

//RUN BASIC CELL BALANCING FOR ALL DEVICES
void StopCB( uint8_t Chipaddr) // add chip address, CB channel ,
{
//START BALANCING
WriteReg(Chipaddr, BAL_CTRL2, 0x00, 1, FRMWRT_SGL_W); //auto balance and BAL_GO
}

//RUN BASIC REVERSE ADDRESSING SEQUENCE
void ReverseAddressing()
{
//CHANGE BASE DEVICE DIRECTION
WriteReg(0, CONTROL1, 0x80, 1, FRMWRT_SGL_W);

//CHANGE REST OF STACK DIRECTION
WriteReg(0, CONTROL1, 0x80, 1, FRMWRT_REV_ALL_W);

//DO NORMAL AUTO ADDRESS SEQUENCE, BUT FOR DIR1_ADDR
//DUMMY WRITE TO SNCHRONIZE ALL DAISY CHAIN DEVICES DLL (IF A DEVICE RESET OCCURED PRIOR TO THIS)
WriteReg(0, OTP_ECC_DATAIN1, 0X00, 1, FRMWRT_ALL_W);
WriteReg(0, OTP_ECC_DATAIN2, 0X00, 1, FRMWRT_ALL_W);
WriteReg(0, OTP_ECC_DATAIN3, 0X00, 1, FRMWRT_ALL_W);
WriteReg(0, OTP_ECC_DATAIN4, 0X00, 1, FRMWRT_ALL_W);
WriteReg(0, OTP_ECC_DATAIN5, 0X00, 1, FRMWRT_ALL_W);
WriteReg(0, OTP_ECC_DATAIN6, 0X00, 1, FRMWRT_ALL_W);
WriteReg(0, OTP_ECC_DATAIN7, 0X00, 1, FRMWRT_ALL_W);
WriteReg(0, OTP_ECC_DATAIN8, 0X00, 1, FRMWRT_ALL_W);

//ENABLE AUTO ADDRESSING MODE, WHILE KEEPING REVERSE DIRECTION
WriteReg(0, CONTROL1, 0X81, 1, FRMWRT_ALL_W);

//SET ADDRESSES FOR EVERY BOARD (REVERSE DIRECTION)
for(currentBoard=0; currentBoard<TOTALBOARDS; currentBoard++)
{
WriteReg(0, DIR1_ADDR, currentBoard, 1, FRMWRT_ALL_W);
}

WriteReg(0, COMM_CTRL, 0x02, 1, FRMWRT_ALL_W); //set everything as a stack device first

if(TOTALBOARDS==1) //if there's only 1 board, it's the base AND top of stack, so change it to those
{
WriteReg(0, COMM_CTRL, 0x01, 1, FRMWRT_SGL_W);
}
else //otherwise set the base and top of stack individually
{
WriteReg(0, COMM_CTRL, 0x00, 1, FRMWRT_SGL_W);
WriteReg(TOTALBOARDS-1, COMM_CTRL, 0x03, 1, FRMWRT_SGL_W);
}

//SYNCRHONIZE THE DLL WITH A THROW-AWAY READ
ReadReg(0, OTP_ECC_DATAIN1, response_frame2, 1, 0, FRMWRT_ALL_R);
ReadReg(0, OTP_ECC_DATAIN2, response_frame2, 1, 0, FRMWRT_ALL_R);
ReadReg(0, OTP_ECC_DATAIN3, response_frame2, 1, 0, FRMWRT_ALL_R);
ReadReg(0, OTP_ECC_DATAIN4, response_frame2, 1, 0, FRMWRT_ALL_R);
ReadReg(0, OTP_ECC_DATAIN5, response_frame2, 1, 0, FRMWRT_ALL_R);
ReadReg(0, OTP_ECC_DATAIN6, response_frame2, 1, 0, FRMWRT_ALL_R);
ReadReg(0, OTP_ECC_DATAIN7, response_frame2, 1, 0, FRMWRT_ALL_R);
ReadReg(0, OTP_ECC_DATAIN8, response_frame2, 1, 0, FRMWRT_ALL_R);

////OPTIONAL: read back all device addresses
//for(currentBoard=0; currentBoard<TOTALBOARDS; currentBoard++)
//{
// ReadReg(currentBoard, DIR0_ADDR, response_frame2, 1, 0, FRMWRT_SGL_R);
// printf("board %d\n",response_frame2[4]);
//}

//RESET ANY COMM FAULT CONDITIONS FROM STARTUP
WriteReg(0, FAULT_RST2, 0x03, 1, FRMWRT_ALL_W);
}
//***************************
//END MISCELLANEOUS FUNCTIONS
//***************************

void Wake79616(void) {

LPUART_SoftwareReset(DEMO_LPUART);
LPUART_Deinit(DEMO_LPUART);
IOMUXC_SetPinMux( IOMUXC_GPIO_AD_24_GPIO9_IO23, 0U);
IOMUXC_SetPinConfig( IOMUXC_GPIO_AD_24_GPIO9_IO23, 2); //2
GPIO_PinInit(BOARD_UART_TX_GPIO, BOARD_UART_TX_GPIO_PIN, &UARTtx_config);
GPIO_PinWrite(BOARD_UART_TX_GPIO, BOARD_UART_TX_GPIO_PIN, 0U);

SDK_DelayAtLeastUs((2500), SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
// delayus(2500); // WAKE ping = 2ms to 2.5ms

IOMUXC_SetPinMux( IOMUXC_GPIO_AD_24_LPUART1_TXD, 0U);
IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_24_LPUART1_TXD, 0x02U);

LPUART_GetDefaultConfig(&config);
config.baudRate_Bps = BOARD_DEBUG_UART_BAUDRATE;
config.enableTx = true;
config.enableRx = true;

LPUART_Init(DEMO_LPUART, &config, DEMO_LPUART_CLK_FREQ);
LPUART_TransferCreateHandle(DEMO_LPUART, &g_lpuartHandle, LPUART_UserCallback, NULL);
}

/************************************
********** AFE 进入SHUTDOWN
*************************************/
void SD79616(void) {
LPUART_SoftwareReset(DEMO_LPUART);
LPUART_Deinit(DEMO_LPUART);
IOMUXC_SetPinMux( IOMUXC_GPIO_AD_24_GPIO9_IO23, 0U);
IOMUXC_SetPinConfig( IOMUXC_GPIO_AD_24_GPIO9_IO23, 0x00);
GPIO_PinInit(BOARD_UART_TX_GPIO, BOARD_UART_TX_GPIO_PIN, &UARTtx_config);
GPIO_PinWrite(BOARD_UART_TX_GPIO, BOARD_UART_TX_GPIO_PIN, 0U);

SDK_DelayAtLeastUs((9000), SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
// delayus(9000); // SD ping = 7ms to 10ms

IOMUXC_SetPinMux( IOMUXC_GPIO_AD_24_LPUART1_TXD, 0U);
IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_24_LPUART1_TXD, 0x02U);

LPUART_GetDefaultConfig(&config);
config.baudRate_Bps = 1000000;//BOARD_DEBUG_UART_BAUDRATE;
config.enableTx = true;
config.enableRx = true;
LPUART_Init(DEMO_LPUART, &config, DEMO_LPUART_CLK_FREQ);
LPUART_TransferCreateHandle(DEMO_LPUART, &g_lpuartHandle, LPUART_UserCallback, NULL);
}

/************************************
********** AFE SLEEP to ACTIVE 
*************************************/
void StA79616(void) {
LPUART_SoftwareReset(DEMO_LPUART);
LPUART_Deinit(DEMO_LPUART);
IOMUXC_SetPinMux( IOMUXC_GPIO_AD_24_GPIO9_IO23, 0U);
IOMUXC_SetPinConfig( IOMUXC_GPIO_AD_24_GPIO9_IO23, 0x00U);
GPIO_PinInit(BOARD_UART_TX_GPIO, BOARD_UART_TX_GPIO_PIN, &UARTtx_config);
GPIO_PinWrite(BOARD_UART_TX_GPIO, BOARD_UART_TX_GPIO_PIN, 0U);

SDK_DelayAtLeastUs((250), SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
// delayus(250); // StA ping = 250us to 300us

IOMUXC_SetPinMux( IOMUXC_GPIO_AD_24_LPUART1_TXD, 0U);
IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_24_LPUART1_TXD, 0x02U);

LPUART_GetDefaultConfig(&config);
config.baudRate_Bps = 1000000;//BOARD_DEBUG_UART_BAUDRATE;
config.enableTx = true;
config.enableRx = true;

LPUART_Init(DEMO_LPUART, &config, DEMO_LPUART_CLK_FREQ);
LPUART_TransferCreateHandle(DEMO_LPUART, &g_lpuartHandle, LPUART_UserCallback, NULL);
}
/************************************
********** AFE reset
*************************************/
void HWRST79616(void) {
LPUART_SoftwareReset(DEMO_LPUART);
LPUART_Deinit(DEMO_LPUART);
IOMUXC_SetPinMux( IOMUXC_GPIO_AD_24_GPIO9_IO23, 0U);
IOMUXC_SetPinConfig( IOMUXC_GPIO_AD_24_GPIO9_IO23, 0x06U);
GPIO_PinInit(BOARD_UART_TX_GPIO, BOARD_UART_TX_GPIO_PIN, &UARTtx_config);
GPIO_PinWrite(BOARD_USER_LED_GPIO, BOARD_USER_LED_GPIO_PIN, 0U);

SDK_DelayAtLeastUs((36000), SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
// delayus(36000); // StA ping = 36ms

IOMUXC_SetPinMux( IOMUXC_GPIO_AD_24_LPUART1_TXD, 0U);
IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_24_LPUART1_TXD, 0x02U);

LPUART_GetDefaultConfig(&config);
config.baudRate_Bps = 1000000;//BOARD_DEBUG_UART_BAUDRATE;
config.enableTx = true;
config.enableRx = true;

LPUART_Init(DEMO_LPUART, &config, DEMO_LPUART_CLK_FREQ);
LPUART_TransferCreateHandle(DEMO_LPUART, &g_lpuartHandle, LPUART_UserCallback, NULL);
}

/*!
* @brief Main function
*/
int main(void)
{
char ch;

/* Init board hardware. */
BOARD_ConfigMPU();
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();

PRINTF("hello world.\r\n");

uint32_t i;
int j = 0;
int currentBoard = 0;
/* lpuart_config_t config;
config.baudRate_Bps = 1000000U;
config.parityMode = kLPUART_ParityDisabled;
config.stopBitCount = kLPUART_OneStopBit;
config.txFifoWatermark = 0;
config.rxFifoWatermark = 0; */


LPUART_GetDefaultConfig(&config);
config.baudRate_Bps = 1000000;//BOARD_DEBUG_UART_BAUDRATE;
config.enableTx = true;
config.enableRx = true;

LPUART_Init(DEMO_LPUART, &config, DEMO_LPUART_CLK_FREQ);
LPUART_TransferCreateHandle(DEMO_LPUART, &g_lpuartHandle, LPUART_UserCallback, NULL);

/************* got a GPT and init it **********************/
/************* this GPT just for****************************/
// gpt_init_A( gptConfig_6 ) ;
// gpt_init_A( gptConfig_5 ) ;

float cellVoltage;
uint16_t rawData;
int boardByteStart;
uint8_t tmp1;
//INITIALIZE BQ79616-Q1
//need 2 wakes as this particular microcontroller outputs RX=0 by default, and so puts devices into hardware reset while the program is being loaded
Wake79616();
SDK_DelayAtLeastUs((12*TOTALBOARDS*1000), SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
// delayms(12*TOTALBOARDS); //wake tone duration is ~1.6ms per board + 10ms per board for each device to wake up from shutdown = 11.6ms per 616 board (rounded to 12ms since variable used is an integer)
Wake79616();
SDK_DelayAtLeastUs((12*TOTALBOARDS*1000), SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
// delayms(12*TOTALBOARDS); //wake tone duration is ~1.6ms per board + 10ms per board for each device to wake up from shutdown = 11.6ms per 616 board (rounded to 12ms since variable used is an integer)

AutoAddress();
SDK_DelayAtLeastUs((4000), SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
// delayus(4000); //4ms total required after shutdown to wake transition for AFE settling time, this is for top device only
WriteReg(0, FAULT_MSK2, 0x40, 1, FRMWRT_ALL_W); //MASK CUST_CRC SO CONFIG CHANGES DON'T FLAG A FAULT
ResetAllFaults(0, FRMWRT_ALL_W); //CLEAR ALL FAULTS

//VARIABLES


//OPTIONAL EXAMPLE FUNCTIONS
//RunCB();
//ReverseAddressing();

//set up the main ADC
WriteReg(0, ACTIVE_CELL, 0x0A, 1, FRMWRT_ALL_W); //set all cells to active
WriteReg(0, ADC_CONF1, 0x02, 1, FRMWRT_ALL_W); //26Hz LPF_Vcell (38ms average)
WriteReg(0, ADC_CTRL1, 0x0E, 1, FRMWRT_ALL_W); //continuous run, LPF enabled and MAIN_GO

SDK_DelayAtLeastUs((38000+5*TOTALBOARDS), SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);


//**********
//MAIN LOOP
//**********
do
{
//*******************
//READ CELL VOLTAGES
//*******************
//reset variables
i = 0;
currentBoard = 0;

//clear out the array so we know we have fresh data every loop
memset(response_frame,0,sizeof(response_frame));

//wait single round robin cycle time + reclocking delay for each device, every loop
//delayus(192+5*TOTALBOARDS);
SDK_DelayAtLeastUs((192+5*TOTALBOARDS), SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);

//read all the values (HI/LO for each cell = 32 total)
// ReadReg(0, VCELL16_HI, response_frame, (16+19)*2, 0, FRMWRT_ALL_R);
ReadReg(0, VCELL16_HI, response_frame, (16)*2, 0, FRMWRT_ALL_R);
/* ***********************************************
* NOTE: SOME COMPUTERS HAVE ISSUES TRANSMITTING A LARGE AMOUNT OF DATA VIA PRINTF STATEMENTS.
* THE FOLLOWING PRINTOUT OF THE RESPONSE DATA IS NOT GUARANTEED TO WORK ON ALL SYSTEMS.
* *********************************************** */

//format and print the resultant response frame
// printf("\n"); //start with a newline to add some extra spacing between loop
for(currentBoard=0; currentBoard<TOTALBOARDS; currentBoard++)
{

//go through each byte in the current board (32 bytes = 16 cells * 2 bytes each)
for(i=0; i<32; i+=2)
{
//each board responds with 32 data bytes + 6 header bytes
//so need to find the start of each board by doing that * currentBoard
boardByteStart = (16*2+6)*currentBoard;

//convert the two individual bytes of each cell into a single 16 bit data item (by bit shifting)
rawData = (response_frame[boardByteStart+i+4] << 8) | response_frame[boardByteStart+i+5];

//cast as a signed 16 bit data item, and multiply by 190.73uV to get an actual voltage
cellVoltage = (rawData)*1.9073;

//print the voltages - it is (32-i)/2 because cells start from 16 down to 1
//and there are 2 bytes per cell (i value is twice the cell number)
AFEdata[currentBoard].MainData_p.AFEVcell[15-j] = cellVoltage;
}

//convert the two individual bytes of each cell into a single 16 bit data item (by bit shifting)

}
//**********************
//END READ CELL VOLTAGES
//**********************
}while(1);

}

  • when I wakeup 79616  the  NFAULT output low like this,is that right? (Pink is the wake-up signal, yellow is NFAULT)

  • i record all MCU send data  from power on

    D0 03 43 00 F9 D4
    D0 03 44 00 FB E4
    D0 03 45 00 FA 74
    D0 03 46 00 FA 84
    D0 03 47 00 FB 14
    D0 03 48 00 FE E4
    D0 03 49 00 FF 74
    D0 03 4A 00 FF 84
    D0 03 09 01 0F 74
    D0 03 06 00 CB 44
    D0 03 08 02 4E E5
    90 00 03 08 01 D2 1D
    C0 03 43 00 FD 14
    C0 03 44 00 FF 24
    C0 03 45 00 FE B4
    C0 03 46 00 FE 44
    C0 03 47 00 FF D4
    C0 03 48 00 FA 24
    C0 03 49 00 FB B4
    C0 03 4A 00 FB 44
    D0 03 32 03 9D 85
    D0 00 19 7F 72 94
    D0 00 17 40 36 E4
    C0 05 0C 01 E8 E5
    91 00 00 36 00 00 FC 94
    D1 03 31 FF FF 88 29
    D0 00 03 0A B8 13
    D0 00 07 02 BB 15
    D0 03 0D 0E 4D B0
    C0 05 68 1F 42 2D
  • Hi  ,

    If you are using the single BQ79616 connected to MCU, we don't need to do auto addressing ( you can avoid calling auto addressing function ). After sending the 'wake ping', you should be able to read the data from BQ79616 using single device read ( device id 0 ) or broadcast read. 

    Regarding the 'NFAULT' going low after wake ping, indicates some active faults in the system. Once you are able to read, you can read the fault register to understand what is failing.

    Can you capture scope shots the AVDD, DVDD and RX line of BQ79616 ( TX from MCU ). If possible, capture UART RX and TX line using the logic analyzer to understand what commands are sent and received on the UART and share the logs.

  • Hi  Ravichandra Sereddy Thipperudra Reddy

    Thank you for your reply

    I have solved this problem, but I don't understand the reason.

    I used serial debugging software to receive instructions from the MCU, and all the instructions were correct.

    Afterwards, I added a debugging breakpoint before sending the instructions, and that was successful. Therefore, I added a 100us delay before sending data to the MCU every time