Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
bq79606.cpp
00001 #include "mbed.h" 00002 #include "bq79606.h" 00003 00004 int bRes = 0; 00005 int count = 10000; 00006 uint8_t pFrame[(MAXBYTES+6)*TOTALBOARDS]; 00007 BYTE bBuf[8]; 00008 BYTE bReturn = 0; 00009 BYTE response_frame2[(MAXBYTES+6)*TOTALBOARDS]; 00010 BYTE bFrame[(2+6)*TOTALBOARDS]; 00011 int nCurrentBoard = 0; 00012 00013 extern Serial bms, pc1; 00014 extern DigitalIn bmsFault; 00015 extern DigitalOut bmsWakeUp; 00016 00017 void sendUART(int length, uint8_t * data){ 00018 //pc1.printf("SENDING TO BOARD\n"); 00019 for(int i = 0; i < length; i++) { 00020 //pc1.putc(data[i]); 00021 bms.putc(data[i]); 00022 } 00023 //wait_ms(1); 00024 } 00025 00026 void Wake79606(){ 00027 bmsWakeUp = 1; 00028 wait_us(275); 00029 bmsWakeUp = 0; 00030 wait_us(275); 00031 bmsWakeUp = 1; 00032 00033 //NMOS TRANSISTOR LOGIC 00034 00035 /*bmsWakeUp = 0; 00036 wait_ms(50); 00037 bmsWakeUp = 1; 00038 wait_ms(50); 00039 bmsWakeUp = 0;*/ 00040 } 00041 00042 void AutoAddress() 00043 { 00044 memset(response_frame2,0,sizeof(response_frame2)); //clear out the response frame buffer 00045 00046 //dummy write to ECC_TEST (sync DLL) 00047 //WriteReg(0, ECC_TEST, 0x00, 1, FRMWRT_ALL_NR); 00048 00049 //clear CONFIG in case it is set 00050 WriteReg(0, CONFIG, 0x00, 1, FRMWRT_ALL_NR); 00051 00052 //enter auto addressing mode 00053 WriteReg(0, CONTROL1, 0x01, 1, FRMWRT_ALL_NR); 00054 00055 //set addresses for all boards in daisy-chain 00056 for (nCurrentBoard = 0; nCurrentBoard < TOTALBOARDS; nCurrentBoard++) 00057 { 00058 WriteReg(nCurrentBoard, DEVADD_USR, nCurrentBoard, 1, FRMWRT_ALL_NR); 00059 } 00060 00061 //set all devices as a stack device 00062 //WriteReg(0, CONFIG, 0x02, 1, FRMWRT_ALL_NR); 00063 00064 //if there's only 1 board, it's the base AND the top of stack, so change it to those 00065 //if(TOTALBOARDS==1) 00066 //{ 00067 WriteReg(0, CONFIG, 0x01, 1, FRMWRT_SGL_NR); 00068 //} 00069 //otherwise set the base and top of stack individually 00070 /*else 00071 { 00072 WriteReg(0, CONFIG, 0x00, 1, FRMWRT_SGL_NR); //base 00073 WriteReg(TOTALBOARDS-1, CONFIG, 0x03, 1, FRMWRT_SGL_NR); //top of stack 00074 }*/ 00075 00076 //dummy read from ECC_TEST (sync DLL) 00077 //ReadReg(TOTALBOARDS-1, ECC_TEST, response_frame2, 1, 0, FRMWRT_ALL_R); 00078 00079 //OPTIONAL: read back all device addresses 00080 WriteReg(0, COMM_TO, 0x00, 1, FRMWRT_ALL_NR); //Disable communication timeout because printf takes a long time 00081 for (nCurrentBoard = 0; nCurrentBoard < TOTALBOARDS; nCurrentBoard++) { 00082 memset(response_frame2, 0, sizeof(response_frame2)); 00083 ReadReg(nCurrentBoard, DEVADD_USR, response_frame2, 1, 0, FRMWRT_SGL_R); 00084 //printf("Board %d=%02x\n",nCurrentBoard,response_frame2[4]); 00085 } 00086 } 00087 //************************** 00088 //END AUTO ADDRESS SEQUENCE 00089 //************************** 00090 00091 00092 //************************ 00093 //WRITE AND READ FUNCTIONS 00094 //************************ 00095 int WriteReg(BYTE bID, uint16_t wAddr, uint64_t dwData, BYTE bLen, BYTE bWriteType) { 00096 // device address, register start address, data bytes, data length, write type (single, broadcast, stack) 00097 bRes = 0; 00098 memset(bBuf,0,sizeof(bBuf)); 00099 switch (bLen) { 00100 case 1: 00101 bBuf[0] = dwData & 0x00000000000000FF; 00102 bRes = WriteFrame(bID, wAddr, bBuf, 1, bWriteType); 00103 break; 00104 case 2: 00105 bBuf[0] = (dwData & 0x000000000000FF00) >> 8; 00106 bBuf[1] = dwData & 0x00000000000000FF; 00107 bRes = WriteFrame(bID, wAddr, bBuf, 2, bWriteType); 00108 break; 00109 case 3: 00110 bBuf[0] = (dwData & 0x0000000000FF0000) >> 16; 00111 bBuf[1] = (dwData & 0x000000000000FF00) >> 8; 00112 bBuf[2] = dwData & 0x00000000000000FF; 00113 bRes = WriteFrame(bID, wAddr, bBuf, 3, bWriteType); 00114 break; 00115 case 4: 00116 bBuf[0] = (dwData & 0x00000000FF000000) >> 24; 00117 bBuf[1] = (dwData & 0x0000000000FF0000) >> 16; 00118 bBuf[2] = (dwData & 0x000000000000FF00) >> 8; 00119 bBuf[3] = dwData & 0x00000000000000FF; 00120 bRes = WriteFrame(bID, wAddr, bBuf, 4, bWriteType); 00121 break; 00122 case 5: 00123 bBuf[0] = (dwData & 0x000000FF00000000) >> 32; 00124 bBuf[1] = (dwData & 0x00000000FF000000) >> 24; 00125 bBuf[2] = (dwData & 0x0000000000FF0000) >> 16; 00126 bBuf[3] = (dwData & 0x000000000000FF00) >> 8; 00127 bBuf[4] = dwData & 0x00000000000000FF; 00128 bRes = WriteFrame(bID, wAddr, bBuf, 5, bWriteType); 00129 break; 00130 case 6: 00131 bBuf[0] = (dwData & 0x0000FF0000000000) >> 40; 00132 bBuf[1] = (dwData & 0x000000FF00000000) >> 32; 00133 bBuf[2] = (dwData & 0x00000000FF000000) >> 24; 00134 bBuf[3] = (dwData & 0x0000000000FF0000) >> 16; 00135 bBuf[4] = (dwData & 0x000000000000FF00) >> 8; 00136 bBuf[5] = dwData & 0x00000000000000FF; 00137 bRes = WriteFrame(bID, wAddr, bBuf, 6, bWriteType); 00138 break; 00139 case 7: 00140 bBuf[0] = (dwData & 0x00FF000000000000) >> 48; 00141 bBuf[1] = (dwData & 0x0000FF0000000000) >> 40; 00142 bBuf[2] = (dwData & 0x000000FF00000000) >> 32; 00143 bBuf[3] = (dwData & 0x00000000FF000000) >> 24; 00144 bBuf[4] = (dwData & 0x0000000000FF0000) >> 16; 00145 bBuf[5] = (dwData & 0x000000000000FF00) >> 8; 00146 bBuf[6] = dwData & 0x00000000000000FF; 00147 bRes = WriteFrame(bID, wAddr, bBuf, 7, bWriteType); 00148 break; 00149 case 8: 00150 bBuf[0] = (dwData & 0xFF00000000000000) >> 56; 00151 bBuf[1] = (dwData & 0x00FF000000000000) >> 48; 00152 bBuf[2] = (dwData & 0x0000FF0000000000) >> 40; 00153 bBuf[3] = (dwData & 0x000000FF00000000) >> 32; 00154 bBuf[4] = (dwData & 0x00000000FF000000) >> 24; 00155 bBuf[5] = (dwData & 0x0000000000FF0000) >> 16; 00156 bBuf[6] = (dwData & 0x000000000000FF00) >> 8; 00157 bBuf[7] = dwData & 0x00000000000000FF; 00158 bRes = WriteFrame(bID, wAddr, bBuf, 8, bWriteType); 00159 break; 00160 default: 00161 break; 00162 } 00163 return bRes; 00164 } 00165 00166 int WriteFrame(BYTE bID, uint16_t wAddr, BYTE * pData, BYTE bLen, BYTE bWriteType) { 00167 int bPktLen = 0; 00168 uint8_t * pBuf = pFrame; 00169 uint16_t wCRC; 00170 memset(pFrame, 0x7F, sizeof(pFrame)); 00171 *pBuf++ = 0x80 | (bWriteType) | ((bWriteType & 0x10) ? bLen - 0x01 : 0x00); //Only include blen if it is a write; Writes are 0x90, 0xB0, 0xD0 00172 if (bWriteType == FRMWRT_SGL_R || bWriteType == FRMWRT_SGL_NR) 00173 { 00174 *pBuf++ = (bID & 0x00FF); 00175 } 00176 *pBuf++ = (wAddr & 0xFF00) >> 8; 00177 *pBuf++ = wAddr & 0x00FF; 00178 00179 while (bLen--) 00180 *pBuf++ = *pData++; 00181 00182 bPktLen = pBuf - pFrame; 00183 00184 wCRC = CRC16(pFrame, bPktLen); 00185 *pBuf++ = wCRC & 0x00FF; 00186 *pBuf++ = (wCRC & 0xFF00) >> 8; 00187 bPktLen += 2; 00188 //THIS SEEMS to occasionally drop bytes from the frame. Sometimes is not sending the last frame of the CRC. 00189 //(Seems to be caused by stack overflow, so take precautions to reduce stack usage in function calls) 00190 //sciSend(scilinREG, bPktLen, pFrame); 00191 00192 sendUART(bPktLen, pFrame); 00193 00194 return bPktLen; 00195 } 00196 00197 int ReadReg(BYTE bID, uint16_t wAddr, BYTE * pData, BYTE bLen, uint32_t dwTimeOut, 00198 BYTE bWriteType) { 00199 bRes = 0; 00200 //count = 100000; 00201 if (bWriteType == FRMWRT_SGL_R) { 00202 ReadFrameReq(bID, wAddr, bLen, bWriteType); 00203 //memset(pData, 0, sizeof(pData)); 00204 //sciEnableNotification(scilinREG, SCI_RX_INT); 00205 //sciReceive(scilinREG, bLen + 6, pData); 00206 //while(UART_RX_RDY == 0U && count>0) count--; /*wait*/ 00207 //if(count == 0) printf("COUNT REACHED 0\n"); 00208 //UART_RX_RDY = 0; 00209 bRes = bLen + 6; 00210 /*else if (bWriteType == FRMWRT_STK_R) { 00211 bRes = ReadFrameReq(bID, wAddr, bLen, bWriteType); 00212 memset(pData, 0, sizeof(pData)); 00213 sciEnableNotification(scilinREG, SCI_RX_INT); 00214 sciReceive(scilinREG, (bLen + 6) * (TOTALBOARDS - 1), pData); 00215 while(UART_RX_RDY == 0U && count>0) count--; //wait 00216 UART_RX_RDY = 0; 00217 bRes = (bLen + 6) * (TOTALBOARDS - 1);*/ 00218 } else if (bWriteType == FRMWRT_ALL_R) { 00219 bRes = ReadFrameReq(bID, wAddr, bLen, bWriteType); 00220 /*memset(pData, 0, sizeof(pData)); 00221 sciEnableNotification(scilinREG, SCI_RX_INT); 00222 sciReceive(scilinREG, (bLen + 6) * TOTALBOARDS, pData); 00223 while(UART_RX_RDY == 0U && count>0) count--; //wait 00224 UART_RX_RDY = 0;*/ 00225 bRes = (bLen + 6) * TOTALBOARDS; 00226 } else { 00227 bRes = 0; 00228 } 00229 /*int recBuff[256]; 00230 bRes = 1; 00231 for(int i = 0; i < bRes; i++){ 00232 recBuff[i] = bms.getc(); 00233 //pc1.printf("rec = %d", recBuff[i]); 00234 } 00235 for(int i = 0; i < bRes; i++){ 00236 pc1.printf("rec = %d", recBuff[i]); 00237 }*/ 00238 return bRes; 00239 } 00240 00241 int ReadFrameReq(BYTE bID, uint16_t wAddr, BYTE bByteToReturn, BYTE bWriteType) { 00242 bReturn = bByteToReturn - 1; 00243 00244 if (bReturn > 127) 00245 return 0; 00246 00247 return WriteFrame(bID, wAddr, &bReturn, 1, bWriteType); 00248 } 00249 00250 00251 00252 void init(){ 00253 00254 00255 00256 /* mask all low level faults... user should unmask necessary faults */ 00257 WriteReg(0, GPIO_FLT_MSK, 0x3F, 1, FRMWRT_ALL_NR); //mask GPIO faults 00258 //WriteReg(0, UV_FLT_MSK, 0x3F, 1, FRMWRT_ALL_NR); //mask UV faults 00259 //WriteReg(0, OV_FLT_MSK, 0x3F, 1, FRMWRT_ALL_NR); //mask OV faults 00260 //WriteReg(0, UT_FLT_MSK, 0x3F, 1, FRMWRT_ALL_NR); //mask UT faults 00261 //WriteReg(0, OT_FLT_MSK, 0x3F, 1, FRMWRT_ALL_NR); //mask OT faults 00262 WriteReg(0, TONE_FLT_MSK, 0x07, 1, FRMWRT_ALL_NR); //mask all tone faults 00263 WriteReg(0, COMM_UART_FLT_MSK, 0x07, 1, FRMWRT_ALL_NR); //mask UART faults 00264 WriteReg(0, COMM_UART_RC_FLT_MSK, 0x3F, 1, FRMWRT_ALL_NR); //mask UART fault contd 00265 WriteReg(0, COMM_UART_RR_FLT_MSK, 0x3F, 1, FRMWRT_ALL_NR); 00266 WriteReg(0, COMM_UART_TR_FLT_MSK, 0x03, 1, FRMWRT_ALL_NR); 00267 WriteReg(0, COMM_COMH_FLT_MSK, 0x3F, 1, FRMWRT_ALL_NR); 00268 WriteReg(0, COMM_COMH_RC_FLT_MSK, 0x3F, 1, FRMWRT_ALL_NR); 00269 WriteReg(0, COMM_COMH_RR_FLT_MSK, 0x3F, 1, FRMWRT_ALL_NR); 00270 WriteReg(0, COMM_COMH_TR_FLT_MSK, 0x03, 1, FRMWRT_ALL_NR); 00271 WriteReg(0, COMM_COML_FLT_MSK, 0x3F, 1, FRMWRT_ALL_NR); 00272 WriteReg(0, COMM_COML_RC_FLT_MSK, 0x3F, 1, FRMWRT_ALL_NR); 00273 WriteReg(0, COMM_COML_RR_FLT_MSK, 0x3F, 1, FRMWRT_ALL_NR); 00274 WriteReg(0, COMM_COML_TR_FLT_MSK, 0x03, 1, FRMWRT_ALL_NR); 00275 WriteReg(0, OTP_FLT_MSK, 0x07, 1, FRMWRT_ALL_NR); // mask otp faults 00276 WriteReg(0, RAIL_FLT_MSK, 0xFF, 1, FRMWRT_ALL_NR); //mask power rail faults 00277 WriteReg(0, SYSFLT1_FLT_MSK, 0x7F, 1, FRMWRT_ALL_NR); //sys fault mask 1 00278 WriteReg(0, SYSFLT2_FLT_MSK, 0xFF, 1, FRMWRT_ALL_NR); //sys fault mask 2 00279 WriteReg(0, SYSFLT3_FLT_MSK, 0x7F, 1, FRMWRT_ALL_NR); //sys fault mask 3 00280 WriteReg(0, OVUV_BIST_FLT_MSK, 0x03, 1, FRMWRT_ALL_NR); //mask ov/uv bist faults 00281 WriteReg(0, OTUT_BIST_FLT_MSK, 0xFF, 1, FRMWRT_ALL_NR); 00282 00283 WriteReg(0, CELL_ADC_CTRL, 0x07, 1, FRMWRT_ALL_NR); //enables ADC for all 6 cell channels 00284 WriteReg(0, OVUV_CTRL, 0x3F, 1, FRMWRT_ALL_NR); //enable all cell ov/uv 00285 WriteReg(0, UV_THRESH, 0x53, 1, FRMWRT_ALL_NR); //sets cell UV to 2.8V 00286 WriteReg(0, OV_THRESH, 0x5B, 1, FRMWRT_ALL_NR); //sets cell OV to 4.3V 00287 00288 WriteReg(0, GPIO_ADC_CONF, 0x3F, 1, FRMWRT_ALL_NR); //configure GPIO as AUX voltage (absolute voltage, set to 0 for ratiometric) 00289 00290 WriteReg(0, AUX_ADC_CONF, 0x08, 1, FRMWRT_ALL_NR); //1MHz AUX sample rate, 128 decimation ratio 00291 WriteReg(0, CELL_ADC_CONF1, 0x67, 1, FRMWRT_ALL_NR); //256 decimation ratio, 1MHz sample. 1.2 Hz LPF 00292 WriteReg(0, CELL_ADC_CONF2, 0x00, 1, FRMWRT_ALL_NR); //single conversion 00293 WriteReg(0, CONTROL2, 0x01, 1, FRMWRT_ALL_NR); //CELL_ADC_GO = 1 00294 ///enable continuous sampling. Otherwise, single conversions with CONTROL2[CELL_ADC_GO] 00295 //WriteReg(0,CELL_ADC_CONF2, 0x0A,1,FRMWRT_ALL_NR);//continuous sampling with 5ms interval 00296 WriteReg(0, CONTROL2, 0x10, 1, FRMWRT_ALL_NR);// enable TSREF to give enough settling time 00297 wait_ms(2); // provides settling time for TSREF 00298 00299 WriteReg(0, DIAG_CTRL2, 0x41, 1, FRMWRT_ALL_NR); //set AUX ADC to measure cell 1 00300 WriteReg(0, GPIO1_CONF, 0x20, 1, FRMWRT_ALL_NR); //configure GPIO as input 00301 00302 WriteReg(0, AUX_ADC_CTRL1, 0x10, 1, FRMWRT_ALL_NR); //enable GPIO1 00303 } 00304 00305 00306 00307 00308 00309 00310 00311 // CRC16 TABLE 00312 // ITU_T polynomial: x^16 + x^15 + x^2 + 1 00313 const uint16_t crc16_table[256] = { 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 00314 0x03C0, 0x0280, 0xC241, 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 00315 0xC481, 0x0440, 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 00316 0x0E40, 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, 00317 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0x1E00, 00318 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1, 00319 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 00320 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, 0xF001, 0x30C0, 0x3180, 0xF141, 00321 0x3300, 0xF3C1, 0xF281, 0x3240, 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 00322 0x35C0, 0x3480, 0xF441, 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 00323 0x3E80, 0xFE41, 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 00324 0x3840, 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 00325 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0xE401, 00326 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1, 00327 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, 0xA001, 0x60C0, 0x6180, 00328 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740, 00329 0xA501, 0x65C0, 0x6480, 0xA441, 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 00330 0x6FC0, 0x6E80, 0xAE41, 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 00331 0xA881, 0x6840, 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 00332 0xBA41, 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 00333 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, 0x7200, 00334 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, 0x5000, 0x90C1, 00335 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 00336 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 00337 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 00338 0x59C0, 0x5880, 0x9841, 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 00339 0x8A81, 0x4A40, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 00340 0x8C41, 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 00341 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 }; 00342 00343 uint16_t CRC16(BYTE *pBuf, int nLen) { 00344 uint16_t wCRC = 0xFFFF; 00345 int i; 00346 00347 for (i = 0; i < nLen; i++) { 00348 wCRC ^= (*pBuf++) & 0x00FF; 00349 wCRC = crc16_table[wCRC & 0x00FF] ^ (wCRC >> 8); 00350 } 00351 00352 return wCRC; 00353 } 00354 00355 00356 00357 00358 00359 00360 00361 00362 00363 00364 00365 00366 00367 00368 00369 00370
Generated on Sun Jul 17 2022 02:07:50 by
1.7.2