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.
adi_bms_utility.cpp
00001 /** 00002 ******************************************************************************** 00003 * 00004 * @file: adi_bms_utility.c 00005 * 00006 * @brief: This file contains utility functions implementation. 00007 * 00008 * @details: 00009 * 00010 ******************************************************************************* 00011 Copyright(c) 2020 Analog Devices, Inc. All Rights Reserved. This software is 00012 proprietary & confidential to Analog Devices, Inc. and its licensors. By using 00013 this software you agree to the terms of the associated Analog Devices License 00014 Agreement. 00015 ******************************************************************************* 00016 */ 00017 /*! \addtogroup BMS_Driver 00018 * @{ 00019 */ 00020 00021 /*! \addtogroup Driver_Utility 00022 * @{ 00023 */ 00024 00025 /*!< 00026 This documentation provides details about BMS driver APIs and their usage. 00027 Using the BMS Driver Application can: 00028 - Read/Write the configuration registers of the BMS devices stacked in daisy chaining. 00029 - Send commands and Read the Cell Voltages, Aux Voltages and Status registers (Sum of cells, Internal Die temperature etc.) 00030 */ 00031 00032 /*============= I N C L U D E S =============*/ 00033 /*============== D E F I N E S ===============*/ 00034 /*============= E X T E R N A L S ============*/ 00035 /*============= E N U M E R A T O R S ============*/ 00036 00037 #include "adbms2950.h" 00038 #include "pal.h" 00039 /*!<**************************************** BMS Driver APIs definitions ********************************************/ 00040 00041 /*!< 00042 * @brief Precomputed CRC15 Table 00043 */ 00044 const uint16_t Crc15Table[256] = 00045 { 00046 0x0000,0xc599, 0xceab, 0xb32, 0xd8cf, 0x1d56, 0x1664, 0xd3fd, 0xf407, 0x319e, 0x3aac, 00047 0xff35, 0x2cc8, 0xe951, 0xe263, 0x27fa, 0xad97, 0x680e, 0x633c, 0xa6a5, 0x7558, 0xb0c1, 00048 0xbbf3, 0x7e6a, 0x5990, 0x9c09, 0x973b, 0x52a2, 0x815f, 0x44c6, 0x4ff4, 0x8a6d, 0x5b2e, 00049 0x9eb7, 0x9585, 0x501c, 0x83e1, 0x4678, 0x4d4a, 0x88d3, 0xaf29, 0x6ab0, 0x6182, 0xa41b, 00050 0x77e6, 0xb27f, 0xb94d, 0x7cd4, 0xf6b9, 0x3320, 0x3812, 0xfd8b, 0x2e76, 0xebef, 0xe0dd, 00051 0x2544, 0x2be, 0xc727, 0xcc15, 0x98c, 0xda71, 0x1fe8, 0x14da, 0xd143, 0xf3c5, 0x365c, 00052 0x3d6e, 0xf8f7,0x2b0a, 0xee93, 0xe5a1, 0x2038, 0x7c2, 0xc25b, 0xc969, 0xcf0, 0xdf0d, 00053 0x1a94, 0x11a6, 0xd43f, 0x5e52, 0x9bcb, 0x90f9, 0x5560, 0x869d, 0x4304, 0x4836, 0x8daf, 00054 0xaa55, 0x6fcc, 0x64fe, 0xa167, 0x729a, 0xb703, 0xbc31, 0x79a8, 0xa8eb, 0x6d72, 0x6640, 00055 0xa3d9, 0x7024, 0xb5bd, 0xbe8f, 0x7b16, 0x5cec, 0x9975, 0x9247, 0x57de, 0x8423, 0x41ba, 00056 0x4a88, 0x8f11, 0x57c, 0xc0e5, 0xcbd7, 0xe4e, 0xddb3, 0x182a, 0x1318, 0xd681, 0xf17b, 00057 0x34e2, 0x3fd0, 0xfa49, 0x29b4, 0xec2d, 0xe71f, 0x2286, 0xa213, 0x678a, 0x6cb8, 0xa921, 00058 0x7adc, 0xbf45, 0xb477, 0x71ee, 0x5614, 0x938d, 0x98bf, 0x5d26, 0x8edb, 0x4b42, 0x4070, 00059 0x85e9, 0xf84, 0xca1d, 0xc12f, 0x4b6, 0xd74b, 0x12d2, 0x19e0, 0xdc79, 0xfb83, 0x3e1a, 0x3528, 00060 0xf0b1, 0x234c, 0xe6d5, 0xede7, 0x287e, 0xf93d, 0x3ca4, 0x3796, 0xf20f, 0x21f2, 0xe46b, 0xef59, 00061 0x2ac0, 0xd3a, 0xc8a3, 0xc391, 0x608, 0xd5f5, 0x106c, 0x1b5e, 0xdec7, 0x54aa, 0x9133, 0x9a01, 00062 0x5f98, 0x8c65, 0x49fc, 0x42ce, 0x8757, 0xa0ad, 0x6534, 0x6e06, 0xab9f, 0x7862, 0xbdfb, 0xb6c9, 00063 0x7350, 0x51d6, 0x944f, 0x9f7d, 0x5ae4, 0x8919, 0x4c80, 0x47b2, 0x822b, 0xa5d1, 0x6048, 0x6b7a, 00064 0xaee3, 0x7d1e, 0xb887, 0xb3b5, 0x762c, 0xfc41, 0x39d8, 0x32ea, 0xf773, 0x248e, 0xe117, 0xea25, 00065 0x2fbc, 0x846, 0xcddf, 0xc6ed, 0x374, 0xd089, 0x1510, 0x1e22, 0xdbbb, 0xaf8, 0xcf61, 0xc453, 00066 0x1ca, 0xd237, 0x17ae, 0x1c9c, 0xd905, 0xfeff, 0x3b66, 0x3054, 0xf5cd, 0x2630, 0xe3a9, 0xe89b, 00067 0x2d02, 0xa76f, 0x62f6, 0x69c4, 0xac5d, 0x7fa0, 0xba39, 0xb10b, 0x7492, 0x5368, 0x96f1, 0x9dc3, 00068 0x585a, 0x8ba7, 0x4e3e, 0x450c, 0x8095 00069 }; 00070 00071 /** 00072 ******************************************************************************* 00073 * Function: Pec15_Calc 00074 * @brief CRC15 Pec Calculation Function 00075 * 00076 * @details This function calculates and return the CRC15 value 00077 * 00078 * Parameters: 00079 * @param [in] Len Data length 00080 * 00081 * @param [in] *data Data pointer 00082 * 00083 * @return CRC15_Value 00084 * 00085 ******************************************************************************* 00086 */ 00087 uint16_t Pec15_Calc 00088 ( 00089 uint8_t len, /*!< Number of bytes that will be used to calculate a PEC */ 00090 uint8_t *data /*!< Array of data that will be used to calculate a PEC */ 00091 ) 00092 { 00093 uint16_t remainder,addr; 00094 remainder = 16; /*!< initialize the PEC */ 00095 for (uint8_t i = 0; i<len; i++) /*!< loops for each byte in data array */ 00096 { 00097 addr = (((remainder>>7)^data[i])&0xff);/*!< calculate PEC table address */ 00098 remainder = ((remainder<<8)^Crc15Table[addr]); 00099 } 00100 return(remainder*2);/*!< The CRC15 has a 0 in the LSB so the remainder must be multiplied by 2 */ 00101 } 00102 00103 /** 00104 ******************************************************************************* 00105 * Function: Pec10_Calc 00106 * @brief CRC10 Pec Calculation Function 00107 * 00108 * @details This function calculates and return the CRC15 value 00109 * 00110 * Parameters: 00111 * @param [in] Len Data length 00112 * 00113 * @param [in] *data Data pointer 00114 * 00115 * @return CRC15_Value 00116 * 00117 ******************************************************************************* 00118 */ 00119 uint16_t pec10_calc(bool rx_cmd, int len, uint8_t *data) 00120 { 00121 uint16_t remainder = 16; /*!< PEC_SEED; 0000010000 */ 00122 uint16_t polynom = 0x8F; /*!< x10 + x7 + x3 + x2 + x + 1 <- the CRC15 polynomial 100 1000 1111 48F */ 00123 00124 /*!< Perform modulo-2 division, a byte at a time. */ 00125 for (uint8_t pbyte = 0; pbyte < len; ++pbyte) 00126 { 00127 /*!< Bring the next byte into the remainder. */ 00128 remainder ^= (uint16_t)(data[pbyte] << 2); 00129 /*!< Perform modulo-2 division, a bit at a time.*/ 00130 for (uint8_t bit_ = 8; bit_ > 0; --bit_) 00131 { 00132 /*!< Try to divide the current data bit. */ 00133 if ((remainder & 0x200) > 0)/*!<equivalent to remainder & 2^14 simply check for MSB */ 00134 { 00135 remainder = (uint16_t)((remainder << 1)); 00136 remainder = (uint16_t)(remainder ^ polynom); 00137 } 00138 else 00139 { 00140 remainder = (uint16_t)(remainder << 1); 00141 } 00142 } 00143 } 00144 if (rx_cmd == true) 00145 { 00146 remainder ^= (uint16_t)((data[len] & 0xFC) << 2); 00147 /*!< Perform modulo-2 division, a bit at a time */ 00148 for (uint8_t bit_ = 6; bit_ > 0; --bit_) 00149 { 00150 /*!< Try to divide the current data bit */ 00151 if ((remainder & 0x200) > 0)/*!<equivalent to remainder & 2^14 simply check for MSB*/ 00152 { 00153 remainder = (uint16_t)((remainder << 1)); 00154 remainder = (uint16_t)(remainder ^ polynom); 00155 } 00156 else 00157 { 00158 remainder = (uint16_t)((remainder << 1)); 00159 } 00160 } 00161 } 00162 return ((uint16_t)(remainder & 0x3FF)); 00163 } 00164 00165 /** 00166 ******************************************************************************* 00167 * Function: spiSendCmd 00168 * @brief Send command over SPI 00169 * 00170 * @details This function send bms command in spi line 00171 * 00172 * Parameters: 00173 * @param [in] tIC Total IC 00174 * 00175 * @param [in] *ic cell_asic structure pointer 00176 * 00177 * @param [in] tx_cmd Tx command byte array 00178 * 00179 * @return None 00180 * 00181 ******************************************************************************* 00182 */ 00183 void spiSendCmd(uint8_t tx_cmd[2]) 00184 { 00185 uint8_t cmd[4]; 00186 uint16_t cmd_pec; 00187 cmd[0] = tx_cmd[0]; 00188 cmd[1] = tx_cmd[1]; 00189 cmd_pec = Pec15_Calc(2, cmd); 00190 cmd[2] = (uint8_t)(cmd_pec >> 8); 00191 cmd[3] = (uint8_t)(cmd_pec); 00192 adBmsCsLow(); 00193 spiWriteBytes(&cmd[0], 4); 00194 adBmsCsHigh(); 00195 } 00196 00197 /** 00198 ******************************************************************************* 00199 * Function: spiReadData 00200 * @brief Spi Read Data, Lower Level function for adBmsReadData 00201 * 00202 * @details This function send command to DUT and read command corrospond data byte. 00203 * 00204 * Parameters: 00205 * @param [in] tIC Total IC 00206 * 00207 * @param [in] tx_cmd Tx command bytes 00208 * 00209 * @param [in] *rx_data Rx data pointer 00210 * 00211 * @param [in] *pec_error Pec error pointer 00212 * 00213 * @param [in] *cmd_cntr command counter pointer 00214 * 00215 * @return None 00216 * 00217 ******************************************************************************* 00218 */ 00219 void spiReadData 00220 ( 00221 uint8_t tIC, 00222 uint8_t tx_cmd[2], 00223 uint8_t *rx_data, 00224 uint8_t *pec_error, 00225 uint8_t *cmd_cntr, 00226 uint8_t regData_size 00227 ) 00228 { 00229 uint8_t *data, *copyArray, src_address = 0; 00230 uint16_t cmd_pec, received_pec, calculated_pec; 00231 uint8_t BYTES_IN_REG = regData_size; 00232 uint8_t RX_BUFFER = (regData_size * tIC); 00233 00234 data = (uint8_t *)calloc(RX_BUFFER, sizeof(uint8_t)); 00235 copyArray = (uint8_t *)calloc(BYTES_IN_REG, sizeof(uint8_t)); 00236 if((data == NULL) || (copyArray == NULL)) 00237 { 00238 printMsg("Failed to allocate spi read data memory"); 00239 exit(0); 00240 } 00241 else 00242 { 00243 uint8_t cmd[4]; 00244 cmd[0] = tx_cmd[0]; 00245 cmd[1] = tx_cmd[1]; 00246 cmd_pec = Pec15_Calc(2, cmd); 00247 cmd[2] = (uint8_t)(cmd_pec >> 8); 00248 cmd[3] = (uint8_t)(cmd_pec); 00249 adBmsWakeupIc(tIC); 00250 adBmsCsLow(); 00251 spiWriteReadBytes(&cmd[0], &data[0], RX_BUFFER); /*!< Read the configuration data of all ICs on the daisy chain into readdata array */ 00252 adBmsCsHigh(); 00253 for (uint8_t current_ic = 0; current_ic < tIC; current_ic++) /*!< executes for each ic in the daisy chain and packs the data */ 00254 { /*!< Into the r_comm array as well as check the received data for any bit errors */ 00255 for (uint8_t current_byte = 0; current_byte < (BYTES_IN_REG-2); current_byte++) 00256 { 00257 rx_data[(current_ic*BYTES_IN_REG)+current_byte] = data[current_byte + (current_ic*BYTES_IN_REG)]; 00258 } 00259 /*!< Get command counter value */ 00260 cmd_cntr[current_ic] = (data[(current_ic * BYTES_IN_REG) + (BYTES_IN_REG - 2)] >> 2); 00261 /*!< Get received pec value from ic*/ 00262 received_pec = (uint16_t)(((data[(current_ic * BYTES_IN_REG) + (BYTES_IN_REG - 2)] & 0x03) << 8) | data[(current_ic * BYTES_IN_REG) + (BYTES_IN_REG - 1)]); 00263 /*!< Copy each ic correspond data + pec value for calculate data pec */ 00264 memcpy(©Array[0], &data[src_address], BYTES_IN_REG); 00265 src_address = ((current_ic+1) * (regData_size)); 00266 /*!< Calculate data pec */ 00267 calculated_pec = (uint16_t)pec10_calc(true, (BYTES_IN_REG-2), ©Array[0]); 00268 /*!< Match received pec with calculated pec */ 00269 if (received_pec == calculated_pec){ pec_error[current_ic] = 0; }/*!< If no error is there value set to 0 */ 00270 else{ pec_error[current_ic] = 1; } /*!< If error is there value set to 1 */ 00271 } 00272 } 00273 free(data); 00274 free(copyArray); 00275 } 00276 00277 /** 00278 ******************************************************************************* 00279 * Function: spiWriteData 00280 * @brief write data over SPI, Lower Level function for adBmsWriteData 00281 * 00282 * @details This function write the data into bms ic 00283 * 00284 * Parameters: 00285 * @param [in] tIC Total IC 00286 * 00287 * @param [in] tx_cmd Tx command bytes 00288 * 00289 * @param [in] *data Data pointer 00290 * 00291 * @return None 00292 * 00293 ******************************************************************************* 00294 */ 00295 void spiWriteData 00296 ( 00297 uint8_t tIC, 00298 uint8_t tx_cmd[2], 00299 uint8_t *data 00300 ) 00301 { 00302 uint8_t BYTES_IN_REG = TX_DATA; 00303 uint8_t CMD_LEN = 4 + (RX_DATA * tIC); 00304 uint16_t data_pec, cmd_pec; 00305 uint8_t *cmd, copyArray[TX_DATA], src_address = 0; 00306 uint8_t cmd_index; 00307 cmd = (uint8_t *)calloc(CMD_LEN, sizeof(uint8_t)); 00308 if(cmd == NULL) 00309 { 00310 printMsg("Failed to allocate cmd array memory"); 00311 exit(0); 00312 } 00313 else 00314 { 00315 cmd[0] = tx_cmd[0]; 00316 cmd[1] = tx_cmd[1]; 00317 cmd_pec = Pec15_Calc(2, cmd); 00318 cmd[2] = (uint8_t)(cmd_pec >> 8); 00319 cmd[3] = (uint8_t)(cmd_pec); 00320 cmd_index = 4; 00321 /*!< executes for each LTC68xx, this loops starts with the last IC on the stack */ 00322 for (uint8_t current_ic = tIC; current_ic > 0; current_ic--) 00323 { 00324 src_address = ((current_ic-1) * TX_DATA); 00325 /*!< The first configuration written is received by the last IC in the daisy chain */ 00326 for (uint8_t current_byte = 0; current_byte < BYTES_IN_REG; current_byte++) 00327 { 00328 cmd[cmd_index] = data[((current_ic-1)*6)+current_byte]; 00329 cmd_index = cmd_index + 1; 00330 } 00331 /*!< Copy each ic correspond data + pec value for calculate data pec */ 00332 memcpy(©Array[0], &data[src_address], TX_DATA); /*!< dst, src, size */ 00333 /*!< calculating the PEC for each Ics configuration register data */ 00334 data_pec = (uint16_t)pec10_calc(true,BYTES_IN_REG, ©Array[0]); 00335 cmd[cmd_index] = (uint8_t)(data_pec >> 8); 00336 cmd_index = cmd_index + 1; 00337 cmd[cmd_index] = (uint8_t)data_pec; 00338 cmd_index = cmd_index + 1; 00339 } 00340 adBmsCsLow(); 00341 spiWriteBytes(&cmd[0], CMD_LEN); 00342 adBmsCsHigh(); 00343 } 00344 free(cmd); 00345 } 00346 00347 /** 00348 ******************************************************************************* 00349 * Function: adBmsReadData 00350 * @brief Adbms Read Data From Bms ic. 00351 * 00352 * @details This function sends the command read payload, parse data put it in structure and check pec error.(Ex: RDCFGA) 00353 * 00354 * Parameters: 00355 * @param [in] tIC Total IC 00356 * 00357 * @param [in] *ic cell_asic stucture pointer 00358 * 00359 * @param [in] cmd_arg command bytes 00360 * 00361 * @param [in] TYPE Enum type of resistor 00362 * 00363 * @param [in] GRP Enum type of resistor group 00364 * 00365 * @return None 00366 * 00367 ******************************************************************************* 00368 */ 00369 void adBmsReadData(uint8_t tIC, cell_asic *ic, uint8_t cmd_arg[2], TYPE type, GRP group) 00370 { 00371 uint16_t rBuff_size; 00372 uint8_t regData_size; 00373 if(group == ALL_GRP) 00374 { 00375 if(type == Rdalla){rBuff_size = RDALLA_SIZE; regData_size = RDALLA_SIZE;} 00376 else if(type == Rdallb){rBuff_size = RDALLB_SIZE; regData_size = RDALLB_SIZE;} 00377 else if(type == Rdcall){rBuff_size = RDCALL_SIZE; regData_size = RDCALL_SIZE;} 00378 else if(type == Rdasall){rBuff_size = RDASALL_SIZE; regData_size = RDASALL_SIZE;} 00379 else 00380 { 00381 printMsg("Read All cmd wrong type select"); 00382 } 00383 } 00384 else{rBuff_size = (tIC * RX_DATA); regData_size = RX_DATA;} 00385 uint8_t *read_buffer, *pec_error, *cmd_count; 00386 read_buffer = (uint8_t *)calloc(rBuff_size, sizeof(uint8_t)); 00387 pec_error = (uint8_t *)calloc(tIC, sizeof(uint8_t)); 00388 cmd_count = (uint8_t *)calloc(tIC, sizeof(uint8_t)); 00389 if((pec_error == NULL) || (cmd_count == NULL) || (read_buffer == NULL)) 00390 { 00391 printMsg("Failed to allocate memory"); 00392 exit(0); 00393 } 00394 else 00395 { 00396 spiReadData(tIC, &cmd_arg[0], &read_buffer[0], &pec_error[0], &cmd_count[0], regData_size); 00397 switch (type) 00398 { 00399 case Config: 00400 adBms2950ParseConfig(tIC, ic, group, &read_buffer[0]); 00401 for (uint8_t cic = 0; cic < tIC; cic++) 00402 { 00403 ic[cic].cccrc.cfgr_pec = pec_error[cic]; 00404 } 00405 break; 00406 00407 case Vr: 00408 adBms2950VrParseData(tIC, ic, group, &read_buffer[0]); 00409 for (uint8_t cic = 0; cic < tIC; cic++) 00410 { 00411 ic[cic].cccrc.vr_pec = pec_error[cic]; 00412 } 00413 break; 00414 00415 case Rvr: 00416 adBms2950RedVrParseData(tIC, ic, group, &read_buffer[0]); 00417 for (uint8_t cic = 0; cic < tIC; cic++) 00418 { 00419 ic[cic].cccrc.rvr_pec = pec_error[cic]; 00420 } 00421 break; 00422 00423 case Cr: 00424 adBms2950ParseCurrentRegData(tIC, ic, &read_buffer[0]); 00425 for (uint8_t cic = 0; cic < tIC; cic++) 00426 { 00427 ic[cic].cccrc.cr_pec = pec_error[cic]; 00428 } 00429 break; 00430 00431 case Vbat: 00432 adBms2950ParseVbatRegData(tIC, ic, &read_buffer[0]); 00433 for (uint8_t cic = 0; cic < tIC; cic++) 00434 { 00435 ic[cic].cccrc.vbat_pec = pec_error[cic]; 00436 } 00437 break; 00438 00439 case Ivbat: 00440 adBms2950ParseIVbatRegData(tIC, ic, &read_buffer[0]); 00441 for (uint8_t cic = 0; cic < tIC; cic++) 00442 { 00443 ic[cic].cccrc.ivbat_pec = pec_error[cic]; 00444 } 00445 break; 00446 00447 case Oc: 00448 adBms2950ParseOcRegData(tIC, ic, &read_buffer[0]); 00449 for (uint8_t cic = 0; cic < tIC; cic++) 00450 { 00451 ic[cic].cccrc.oc_pec = pec_error[cic]; 00452 } 00453 break; 00454 00455 case AvgCr: 00456 adBms2950ParseAvgCurrentRegData(tIC, ic, &read_buffer[0]); 00457 for (uint8_t cic = 0; cic < tIC; cic++) 00458 { 00459 ic[cic].cccrc.avgcr_pec = pec_error[cic]; 00460 } 00461 break; 00462 00463 case AvgVbat: 00464 adBms2950ParseAvgVbatRegData(tIC, ic, &read_buffer[0]); 00465 for (uint8_t cic = 0; cic < tIC; cic++) 00466 { 00467 ic[cic].cccrc.avgvbat_pec = pec_error[cic]; 00468 } 00469 break; 00470 00471 case AvgIvbat: 00472 adBms2950ParseAvgIVbatRegData(tIC, ic, &read_buffer[0]); 00473 for (uint8_t cic = 0; cic < tIC; cic++) 00474 { 00475 ic[cic].cccrc.avgivbat_pec = pec_error[cic]; 00476 } 00477 break; 00478 00479 case Status: 00480 adBms2950ParseStatus(tIC, ic, group, &read_buffer[0]); 00481 for (uint8_t cic = 0; cic < tIC; cic++) 00482 { 00483 ic[cic].cccrc.stat_pec = pec_error[cic]; 00484 } 00485 break; 00486 00487 case Comm: 00488 adBms2950ParseComm(tIC, ic, &read_buffer[0]); 00489 for (uint8_t cic = 0; cic < tIC; cic++) 00490 { 00491 ic[cic].cccrc.comm_pec = pec_error[cic]; 00492 } 00493 break; 00494 00495 case SID: 00496 adBms2950ParseSID(tIC, ic, &read_buffer[0]); 00497 for (uint8_t cic = 0; cic < tIC; cic++) 00498 { 00499 ic[cic].cccrc.sid_pec = pec_error[cic]; 00500 } 00501 break; 00502 00503 case Rdalla: 00504 // TBD 00505 break; 00506 00507 case Rdallb: 00508 // TBD 00509 break; 00510 00511 case Rdcall: 00512 // TBD 00513 break; 00514 00515 case Rdasall: 00516 // TBD 00517 break; 00518 00519 default: 00520 break; 00521 } 00522 } 00523 free(read_buffer); 00524 free(pec_error); 00525 free(cmd_count); 00526 } 00527 /** 00528 ******************************************************************************* 00529 * Function: adBmsWriteData 00530 * @brief Adbms Write Data into Bms ic. 00531 * 00532 * @details This function write the data to DUT. (EX: WRCFGA) 00533 * 00534 * Parameters: 00535 * @param [in] tIC Total IC 00536 * 00537 * @param [in] *ic cell_asic stucture pointer 00538 * 00539 * @param [in] cmd_arg command bytes 00540 * 00541 * @param [in] TYPE Enum type of resistor 00542 * 00543 * @param [in] GRP Enum type of resistor group 00544 * 00545 * @return None 00546 * 00547 ******************************************************************************* 00548 */ 00549 void adBmsWriteData(uint8_t tIC, cell_asic *ic, uint8_t cmd_arg[2], TYPE type, GRP group) 00550 { 00551 uint8_t data_len = TX_DATA, write_size = (TX_DATA * tIC); 00552 uint8_t *write_buffer = (uint8_t *)calloc(write_size, sizeof(uint8_t)); 00553 if(write_buffer == NULL) 00554 { 00555 printMsg("Failed to allocate write_buffer array memory"); 00556 exit(0); 00557 } 00558 else 00559 { 00560 switch (type) 00561 { 00562 case Config: 00563 switch (group) 00564 { 00565 case A: 00566 adBms2950CreateConfiga(tIC, &ic[0]); 00567 for (uint8_t cic = 0; cic < tIC; cic++) 00568 { 00569 for (uint8_t data = 0; data < data_len; data++) 00570 { 00571 write_buffer[(cic * data_len) + data] = ic[cic].configa.tx_data[data]; 00572 } 00573 } 00574 break; 00575 case B: 00576 adBms2950CreateConfigb(tIC, &ic[0]); 00577 for (uint8_t cic = 0; cic < tIC; cic++) 00578 { 00579 for (uint8_t data = 0; data < data_len; data++) 00580 { 00581 write_buffer[(cic * data_len) + data] = ic[cic].configb.tx_data[data]; 00582 } 00583 } 00584 break; 00585 } 00586 break; 00587 00588 case Comm: 00589 adBms2950CreateComm(tIC, &ic[0]); 00590 for (uint8_t cic = 0; cic < tIC; cic++) 00591 { 00592 for (uint8_t data = 0; data < data_len; data++) 00593 { 00594 write_buffer[(cic * data_len) + data] = ic[cic].com.tx_data[data]; 00595 } 00596 } 00597 break; 00598 00599 case Clrflag: 00600 adBms2950CreateClrflagData(tIC, &ic[0]); 00601 for (uint8_t cic = 0; cic < tIC; cic++) 00602 { 00603 for (uint8_t data = 0; data < data_len; data++) 00604 { 00605 write_buffer[(cic * data_len) + data] = ic[cic].clrflag.tx_data[data]; 00606 } 00607 } 00608 break; 00609 00610 default: 00611 break; 00612 } 00613 } 00614 adBmsWakeupIc(tIC); 00615 spiWriteData(tIC, cmd_arg, &write_buffer[0]); 00616 free(write_buffer); 00617 } 00618 00619 /** 00620 ******************************************************************************* 00621 * Function: adBmsPollAdc 00622 * @brief PLADC Command. 00623 * 00624 * @details Send poll adc command and retun adc conversion count. 00625 * 00626 * Parameters: 00627 * 00628 * @param [in] tIC Total IC 00629 * 00630 * @param [in] *ic cell_asic structure pointer 00631 * 00632 * @param [in] tx_cmd Tx command byte 00633 * 00634 * @return Pladc_count(uint32_t) 00635 * 00636 ******************************************************************************* 00637 */ 00638 uint32_t adBmsPollAdc(uint8_t tx_cmd[2]) 00639 { 00640 uint32_t pladc_count = 0; 00641 uint8_t cmd[4]; 00642 uint16_t cmd_pec; 00643 uint8_t read_data = 0x00; 00644 uint8_t SDO_Line = 0xFF; 00645 cmd[0] = tx_cmd[0]; 00646 cmd[1] = tx_cmd[1]; 00647 cmd_pec = Pec15_Calc(2, cmd); 00648 cmd[2] = (uint8_t)(cmd_pec >> 8); 00649 cmd[3] = (uint8_t)(cmd_pec); 00650 startTimer(); 00651 adBmsCsLow(); 00652 spiWriteBytes(&cmd[0], 4); 00653 do{ 00654 spiReadBytes(&read_data, 1); 00655 }while(!(read_data == SDO_Line)); 00656 adBmsCsHigh(); 00657 pladc_count = getTimCount(); 00658 stopTimer(); 00659 return(pladc_count); 00660 } 00661 00662 /** @}*/ 00663 /** @}*/
Generated on Thu Oct 13 2022 07:45:26 by
