/* * (c) Copyright 2022 NXP * * NXP Confidential. This software is owned or controlled by NXP and may only be used strictly * in accordance with the applicable license terms. By expressly accepting * such terms or by downloading, installing, activating and/or otherwise using * the software, you are agreeing that you have read, and that you agree to * comply with and are bound by, such license terms. If you do not agree to * be bound by the applicable license terms, then you may not retain, * install, activate or otherwise use the software. * * This file contains sample code only. It is not part of the production code deliverables. */ #ifdef __cplusplus extern "C" { #endif /*================================================================================================== * INCLUDE FILES * 1) system and project includes * 2) needed interfaces from external units * 3) internal and external interfaces from this unit ==================================================================================================*/ #include "CDD_Bcc_775a.h" #include "CDD_Bcc_775a_SL.h" #include "CDD_Bms_common.h" #include "CDD_Bms_tpl3_sl_e2e.h" /* Including project libraries */ #include "Cmu.h" #include "Common.h" #include "FreeMaster.h" /*================================================================================================== * LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS) ==================================================================================================*/ typedef enum { /* Measurement cycle CMU */ BCC_775A_CELL = 1U, BCC_775A_PRMM_AINX = 2U, BCC_775A_VMODULE = 3U, BCC_775A_SEC_AINX = 4U }Bcc_MeasurementType; /*================================================================================================== * LOCAL MACROS ==================================================================================================*/ /***** Configurable *****/ #define BCC_CELL_CNT 14U // Number of cells monitored by each BCC #define BCC_AIN_CNT 8U // Number of analog inputs monitored by each BCC /***** Fixed *****/ /* Communication addresses */ #define BCC_BROADCAST 63U // Transformer Physical Layer broadcast address /* Conversion rates */ #define BCC_VCX_AINX_CONV 154U // MC33775A conversion rate for VCx and AINx measurements in uV/LSB #define BCC_VCMOD_VBAT_CONV 258U // MC33775A conversion rate for VC MODULE and VBAT measurements in mV/LSB - must be divided by 100 /* Number of measurements per type */ #define BCC_PRMM_APP_MEAS 20U // Number of values measured by the PRIMARY chain in APP mode /*================================================================================================== * LOCAL CONSTANTS ==================================================================================================*/ /*================================================================================================== * LOCAL VARIABLES ==================================================================================================*/ /* Measurement results (used by FreeMASTER application) */ volatile sint32 PackVoltage; volatile sint32 ModuleVoltage[BCC_DEVICE_CNT]; volatile sint32 CellVoltage[BCC_CELL_CNT*BCC_DEVICE_CNT]; volatile sint32 AnalogInputsCMU[BCC_AIN_CNT*BCC_DEVICE_CNT]; /* System status (used by FreeMASTER application) */ volatile HVBMS_Errors CMU_ErrorStatusDevice[BCC_DEVICE_CNT]; /* Internal variables */ static Bms_TPL3_SL_E2E_CheckStatusType checkResult; uint8 SequenceId = 1; FMSTR_TSA_TABLE_BEGIN(Cmu_paramters_table) FMSTR_TSA_RW_VAR(PackVoltage, FMSTR_TSA_SINT32) FMSTR_TSA_RW_VAR(ModuleVoltage, FMSTR_TSA_SINT32) FMSTR_TSA_RW_VAR(CellVoltage, FMSTR_TSA_SINT32) FMSTR_TSA_RW_VAR(AnalogInputsCMU, FMSTR_TSA_SINT32) FMSTR_TSA_RW_VAR(CMU_ErrorStatusDevice[0], FMSTR_TSA_USERTYPE(HVBMS_Errors)) FMSTR_TSA_RW_VAR(CMU_ErrorStatusDevice[1], FMSTR_TSA_USERTYPE(HVBMS_Errors)) FMSTR_TSA_RW_VAR(CMU_ErrorStatusDevice[2], FMSTR_TSA_USERTYPE(HVBMS_Errors)) FMSTR_TSA_RW_VAR(CMU_ErrorStatusDevice[3], FMSTR_TSA_USERTYPE(HVBMS_Errors)) FMSTR_TSA_TABLE_END() /*================================================================================================== * GLOBAL CONSTANTS ==================================================================================================*/ /*================================================================================================== * GLOBAL VARIABLES ==================================================================================================*/ /* Error monitoring */ extern uint8 deviceError[BCC_DEVICE_CNT+1]; // BCC device error status extern Phy_ErrorStatusType PhyError; // Phy error status extern HVBMS_States BmsState; /*Bms states*/ /* Phy configuration */ extern Phy_DeviceIdxType PhyIndex; // Phy identifier /* Loopback status */ extern bool isCmuChainBroken; // Loopback feature: status of the main chain /*================================================================================================== * LOCAL FUNCTION PROTOTYPES ==================================================================================================*/ /** * @brief Cell voltage measurement logging function * @details Converts and logs cell voltage measurements on FreeMASTER variables * * @param[in] RawData Raw measurement data extracted from Transaction Descriptor * @param[in] Bcc_MeasurementType Measurement type * @param[in] Length How many measurement values have to be converted from RawData * @param[in] DevAddr Device address for specific BCC device * * @return Std_ReturnType * @retval E_OK The measurement data was retrieved successfully * @retval E_NOT_OK The measurement data was not retrieved successfully */ static Std_ReturnType Cmu_MeasLog( uint16* RawData, Bcc_MeasurementType MsrConversion, uint8 Length, uint8 DevAddr ); /** * @brief PackVoltage calculation function * @details Calculates pack voltage out of the module voltages, as FreeMASTER variable */ static void CalcPackVoltage(void); /*================================================================================================== * LOCAL FUNCTIONS ==================================================================================================*/ /** * @brief Cell voltage measurement logging function * @details Converts and logs cell voltage measurements on FreeMASTER variables * * @param[in] RawData Raw measurement data extracted from Transaction Descriptor * @param[in] MeasChain Measurement chain to read from * @param[in] MeasType Measurement data type to read * @param[in] DevAddr Device address for specific BCC device * * @return Std_ReturnType * @retval E_OK The measurement data was retrieved successfully * @retval E_NOT_OK The measurement data was not retrieved successfully */ static Std_ReturnType Cmu_MeasLog( uint16* RawData, Bcc_MeasurementType MsrConversion, uint8 Length, uint8 DevAddr ) { Std_ReturnType Status = E_OK; uint8 DataIdx; for (DataIdx = 0 ; DataIdx < Length ; DataIdx++) { Status = Bcc_775a_SL_SaM_CheckSMi1(RawData[DataIdx]); if(Status != E_OK) { /*If measurement result invalid return E_NOT_OK*/ return E_NOT_OK; } /* Cell voltages logging */ if(MsrConversion == BCC_775A_CELL) { CellVoltage[((DevAddr-1)*BCC_CELL_CNT)+DataIdx] = (uint32)(RawData[DataIdx] * BCC_VCX_AINX_CONV); } /* Analog inputs logging for the AIN0-3 */ else if(MsrConversion == BCC_775A_PRMM_AINX) { AnalogInputsCMU[((DevAddr-1)*BCC_AIN_CNT)+DataIdx] = (uint32)RawData[DataIdx] * BCC_VCX_AINX_CONV; } /*Analog inputs logging for the AIN4-7 */ else if(MsrConversion == BCC_775A_SEC_AINX) { AnalogInputsCMU[((DevAddr-1)*BCC_AIN_CNT)+DataIdx+4U] = (uint32)RawData[DataIdx] * BCC_VCX_AINX_CONV; } /* Module voltages logging */ else if(MsrConversion == BCC_775A_VMODULE) { ModuleVoltage[(DevAddr-1)] = (uint32)(((*RawData) * BCC_VCMOD_VBAT_CONV) / 100); } else { return E_NOT_OK; } } return Status; } /** * @brief PackVoltage calculation function * @details Calculates pack voltage out of the module voltages, as FreeMASTER variable */ static void CalcPackVoltage(void) { PackVoltage = 0; uint8 DevIdx; /* Sum-up all module voltage values */ for (DevIdx = 0; DevIdx < BCC_DEVICE_CNT ; DevIdx++) { PackVoltage += (ModuleVoltage[DevIdx]); } } /*================================================================================================== * GLOBAL FUNCTIONS ==================================================================================================*/ /** * @brief FreeMASTER CMU variables initialization function * @details Initializes FreeMASTER-watched variables for CMU */ void FMSTR_VariablesInit_Cmu(void) { uint8 Indx = 0; /* Set PackVoltage to 0 */ PackVoltage = 0; /* Set ModuleVoltage table values to 0 for all nodes */ for (Indx = 0; Indx < BCC_DEVICE_CNT ; Indx++) { ModuleVoltage[Indx] = 0; } /* Set CellVoltage table values to 0 for all nodes */ for (Indx = 0; Indx < BCC_CELL_CNT*BCC_DEVICE_CNT ; Indx++) { CellVoltage[Indx] = 0; } /* Set AnalogInputsCMU table values to 0 for all nodes */ for (Indx = 0; Indx < BCC_AIN_CNT*BCC_DEVICE_CNT ; Indx++) { AnalogInputsCMU[Indx] = 0; } /* Initialize CMU errors for all nodes */ for (Indx = 0; Indx < BCC_DEVICE_CNT ; Indx++) { CMU_ErrorStatusDevice[Indx] = 0; } } /** * @brief Configuration of CMU devices function * @details Initializes all CMU devices * * @return HVBMS_Errors The latest error that occurred in the BMS system */ HVBMS_Errors Cmu_Init(void) { Std_ReturnType Status = E_OK; uint8 BCC_Device_Addr = 1; uint16 EnumerateData[BCC_DEVICE_CNT]; /* Initialize Bcc_775a driver */ Status = Bcc_775a_Init(NULL_PTR); Bms_TPL3_SL_E2E_InitState(&BmsTPL3SLE2EConfig); Status |= Bms_TD_Clear(&BmsTDCfg_Tpl3); /* Insert a NOP to wake-up the first device */ Status |= Bcc_775a_COM_InsertNop(BCC_CHAIN_ADDR, BCC_BROADCAST, &BmsTDCfg_Tpl3); /* Insert a PHY event message into the transaction descriptor to wait for the first device to wake-up */ Status |= Bms_TD_InsertPhyEvent(&BmsTDCfg_Tpl3, PHY_TIMER, 2600U); /* Enumerate the devices */ for(BCC_Device_Addr = 1; BCC_Device_Addr <= BCC_DEVICE_CNT; BCC_Device_Addr++) { Status |= Bms_TPL3_SL_E2E_InitDeviceState(&BmsTPL3SLE2EConfig,BCC_CHAIN_ADDR,BCC_Device_Addr); Status |= Bcc_775a_Enumerate(BCC_CHAIN_ADDR, BCC_Device_Addr, &BmsTDCfg_Tpl3); /* Insert a NOP to wake-up the next device */ Status |= Bcc_775a_COM_InsertNop(BCC_CHAIN_ADDR, BCC_BROADCAST, &BmsTDCfg_Tpl3); if (BCC_Device_Addr < BCC_DEVICE_CNT) { /* Insert a PHY event message into the transaction descriptor */ Status |= Bms_TD_InsertPhyEvent(&BmsTDCfg_Tpl3, PHY_TIMER, 2400U); } } /* Read SYS_COM_CFG to see if the devices are enumerated successfully */ for(BCC_Device_Addr = 1; BCC_Device_Addr <= BCC_DEVICE_CNT; BCC_Device_Addr++) { /* Read SYS_COM_CFG to check if device was enumerated */ Status |= Bcc_775a_COM_ReadRegisters(BCC_CHAIN_ADDR, BCC_Device_Addr, MC33775_SYS_COM_CFG_OFFSET, 1U, &BmsTDCfg_Tpl3); /* Tell the SL that a read request happened */ Status |= Bms_TPL3_SL_E2E_LogDeviceRequest(&BmsTPL3SLE2EConfig, SequenceId,BCC_CHAIN_ADDR,BCC_Device_Addr); } /* Call Bcc_775a_Send */ Status = Bms_TD_Send(&BmsTDCfg_Tpl3, &PhyError); if(Status != E_OK) { return ERROR_CMU_ENUMERATE_TD_FILL; } /* Wait until PHY processes the request */ Td_Wait(&BmsTDCfg_Tpl3); if((PhyError != PHY_NO_ERROR) || (BmsTDCfg_Tpl3.PhyTD->Status != PHY_TS_FINISHED)) { return ERROR_CMU_ENUMERATE_TD_SEND; } /* Call E2E_Check to check the integrity of the TD */ Status= Bms_TPL3_SL_E2E_Check(&BmsTPL3SLE2EConfig, &BmsTDCfg_Tpl3, SequenceId, &checkResult); if(Status != E_OK) { CMU_ErrorStatusDevice[checkResult.ErrorDeviceId] = ERROR_CMU_ENUMERATE_E2E_CHECK; return ERROR_CMU_ENUMERATE_E2E_CHECK; } /* Extract the register data from the TD */ for(BCC_Device_Addr = 1; BCC_Device_Addr <= BCC_DEVICE_CNT; BCC_Device_Addr++) { Status = Bms_TPL3_SL_E2E_ExtractData(&BmsTDCfg_Tpl3, BCC_CHAIN_ADDR, BCC_Device_Addr, MC33775_SYS_COM_CFG_OFFSET, 1, &EnumerateData[BCC_Device_Addr-1]); if( (Status != E_OK) && ((EnumerateData[BCC_Device_Addr-1] & MC33775_SYS_COM_CFG_DADD_MSK ) != BCC_Device_Addr)) { CMU_ErrorStatusDevice[BCC_Device_Addr] = ERROR_CMU_ENUMERATE_E2E_EXTRACT; return ERROR_CMU_ENUMERATE_E2E_EXTRACT; } } /* Clear the transaction descriptor */ Bms_TD_Clear(&BmsTDCfg_Tpl3); /* Configure measurements for all devices with no delays between broadcast messages */ Status |= Bcc_775a_MSR_Configure(BCC_CHAIN_ADDR, BCC_BROADCAST, 0U, &BmsTDCfg_Tpl3); /* SetNumNodes to the maximum number of devices, this will command will introduce for each broadcast message */ for(BCC_Device_Addr = 1; BCC_Device_Addr <= BCC_DEVICE_CNT; BCC_Device_Addr++) { Status |= Bcc_775a_SetNumNodes(BCC_CHAIN_ADDR, BCC_Device_Addr,BCC_DEVICE_CNT, &BmsTDCfg_Tpl3); } /* Call Bcc_775a_Send */ Status |= Bms_TD_Send(&BmsTDCfg_Tpl3, &PhyError); if(Status != E_OK) { return ERROR_CMU_INIT_PHASE_CLOSE_TD_FILL; } /* Wait until PHY processes the request */ Td_Wait(&BmsTDCfg_Tpl3); if((PhyError != PHY_NO_ERROR) || (BmsTDCfg_Tpl3.PhyTD->Status != PHY_TS_FINISHED)) { return ERROR_CMU_INIT_PHASE_CLOSE_TD_SEND; } Status = Bms_TD_Clear(&BmsTDCfg_Tpl3); return NO_ERROR; } /** * @brief Cell voltage measurement start-up function * @details Starts cell voltage and analog inputs measurements on all nodes * * @param[in] MeasChain Measurement chain to read from * @param[in] MeasType Measurement data type to read * * @return HVBMS_Errors The latest error that occurred in the BMS system */ HVBMS_Errors Cmu_StartMeas(Bcc_775a_MsrChainType MeasChain, Bcc_775a_MsrMeasurementType MeasType) { Std_ReturnType Status = E_OK; Bcc_775a_MsrBalPauseType BalPause; Bcc_775a_MsrSetModeParamsType SetModeParams; BalPause.BalancingPauseTimer = 0; BalPause.BalancingAutopauseEn = FALSE; SetModeParams.PauseBalancing = FALSE; SetModeParams.OpenLoadNum = MC33775_PRMM_APP_CTRL_VCOLNUM_DISABLED_ENUM_VAL; /* Start primary measurements */ if(isCmuChainBroken == true) { Status |= Bcc_775a_SetMADD(BCC_CHAIN_ADDR,BCC_BROADCAST,true); Status |= Bcc_775a_MSR_StartMeasurements(BCC_CHAIN_ADDR, BCC_BROADCAST, MeasChain, BalPause, &BmsTDCfg_Tpl3); Status |= Bcc_775a_SetMADD(BCC_CHAIN_ADDR,BCC_BROADCAST,false); Status |= Bcc_775a_MSR_StartMeasurements(BCC_CHAIN_ADDR, BCC_BROADCAST, MeasChain, BalPause, &BmsTDCfg_Tpl3); } else { Status |= Bcc_775a_MSR_StartMeasurements(BCC_CHAIN_ADDR, BCC_BROADCAST, MeasChain, BalPause, &BmsTDCfg_Tpl3); } if(MeasType == BCC_775A_MSR_TYPE_APPLICATION) { if(isCmuChainBroken == true) { Status |= Bcc_775a_SetMADD(BCC_CHAIN_ADDR,BCC_BROADCAST,true); Status |= Bcc_775a_MSR_SetMode(BCC_CHAIN_ADDR, BCC_BROADCAST, MeasType, &SetModeParams, &BmsTDCfg_Tpl3); /* Wait 4ms for measurements to be completed */ Status |= Bms_TD_InsertPhyEvent(&BmsTDCfg_Tpl3, PHY_TIMER, 4000); Status |= Bcc_775a_MSR_SetMode(BCC_CHAIN_ADDR, BCC_BROADCAST, MeasType, &SetModeParams, &BmsTDCfg_Tpl3); Status |= Bms_TD_InsertPhyEvent(&BmsTDCfg_Tpl3, PHY_TIMER, 300); /* Insert for the 300 us delay */ Status |= Bcc_775a_COM_InsertNop(BCC_CHAIN_ADDR, BCC_BROADCAST, &BmsTDCfg_Tpl3); Status |= Bcc_775a_SetMADD(BCC_CHAIN_ADDR,BCC_BROADCAST,false); Status |= Bcc_775a_MSR_SetMode(BCC_CHAIN_ADDR, BCC_BROADCAST, MeasType, &SetModeParams, &BmsTDCfg_Tpl3); /* Wait 4ms for measurements to be completed */ Status |= Bms_TD_InsertPhyEvent(&BmsTDCfg_Tpl3, PHY_TIMER, 4000); Status |= Bcc_775a_MSR_SetMode(BCC_CHAIN_ADDR, BCC_BROADCAST, MeasType, &SetModeParams, &BmsTDCfg_Tpl3); Status |= Bms_TD_InsertPhyEvent(&BmsTDCfg_Tpl3, PHY_TIMER, 300); /* Insert for the 300 us delay*/ Status |= Bcc_775a_COM_InsertNop(BCC_CHAIN_ADDR, BCC_BROADCAST, &BmsTDCfg_Tpl3); } else { Status |= Bcc_775a_MSR_SetMode(BCC_CHAIN_ADDR, BCC_BROADCAST, MeasType, &SetModeParams, &BmsTDCfg_Tpl3); /* Wait 4ms for measurements to be completed */ Status |= Bms_TD_InsertPhyEvent(&BmsTDCfg_Tpl3, PHY_TIMER, 4000); Status |= Bcc_775a_MSR_SetMode(BCC_CHAIN_ADDR, BCC_BROADCAST, MeasType, &SetModeParams, &BmsTDCfg_Tpl3); Status |= Bms_TD_InsertPhyEvent(&BmsTDCfg_Tpl3, PHY_TIMER, 300); /* Insert for the 300 us delay */ Status |= Bcc_775a_COM_InsertNop(BCC_CHAIN_ADDR, BCC_BROADCAST, &BmsTDCfg_Tpl3); } } else if(MeasType == BCC_775A_MSR_TYPE_SYNCHRONOUS) { // Reserved for further development } else { // Avoid MISRA errors } /* Call Bcc_775a_Send */ Status |= Bms_TD_Send(&BmsTDCfg_Tpl3, &PhyError); if(Status != E_OK) { return ERROR_CMU_START_MEASUREMENT_TD_FILL; } /* Wait until PHY processes the request */ Td_Wait(&BmsTDCfg_Tpl3); if(PhyError != PHY_NO_ERROR) { return ERROR_CMU_START_MEASUREMENT_TD_SEND; } /* Clear TD after completion */ Status = Bms_TD_Clear(&BmsTDCfg_Tpl3); return NO_ERROR; } /** * @brief Cell voltage measurement reading and conversion function * @details Reads, converts and logs cell voltage measurements from all nodes * * @param[in] MeasChain Measurement chain to read from * @param[in] MeasType Measurement data type to read * * @return HVBMS_Errors The latest error that occurred in the BMS system */ HVBMS_Errors Cmu_ReadMeas(Bcc_775a_MsrChainType MeasChain, Bcc_775a_MsrMeasurementType MeasType) { uint16_t RawData[BCC_PRMM_APP_MEAS]; Std_ReturnType Status = E_OK; uint8 BCC_Device_Addr; for(BCC_Device_Addr = 1; BCC_Device_Addr <= BCC_DEVICE_CNT; BCC_Device_Addr++) { /* Read data from the primary measurement chain */ Status = Bcc_775a_MSR_GetData(BCC_CHAIN_ADDR, BCC_Device_Addr, MeasChain, MeasType, &BmsTDCfg_Tpl3); /* Tell the SL that a read request happened */ Status |= Bms_TPL3_SL_E2E_LogDeviceRequest(&BmsTPL3SLE2EConfig, SequenceId, BCC_CHAIN_ADDR,BCC_Device_Addr); /* Stop primary measurements */ Status |= Bcc_775a_MSR_StopMeasurements(BCC_CHAIN_ADDR, BCC_Device_Addr, MeasChain, &BmsTDCfg_Tpl3); /* Call Bcc_775a_Send */ Status |= Bms_TD_Send(&BmsTDCfg_Tpl3, &PhyError); if(Status != E_OK) { return ERROR_CMU_READ_MEASUREMENTS_TD_FILL; } /* Wait until PHY processes the request */ Td_Wait( &BmsTDCfg_Tpl3); if(PhyError != PHY_NO_ERROR) { return ERROR_CMU_READ_MEASUREMENTS_TD_SEND; } Status= Bms_TPL3_SL_E2E_Check(&BmsTPL3SLE2EConfig, &BmsTDCfg_Tpl3, SequenceId, &checkResult); if(Status != E_OK) { CMU_ErrorStatusDevice[checkResult.ErrorDeviceId-1] = ERROR_CMU_READ_MEASUREMENTS_E2E_CHECK; return ERROR_CMU_READ_MEASUREMENTS_E2E_CHECK; } if((MeasChain == BCC_775A_MSR_CHAIN_PRIMARY ) && (MeasType == BCC_775A_MSR_TYPE_APPLICATION)) { /* Extract 14 cell voltages for each device */ Status = Bms_TPL3_SL_E2E_ExtractData(&BmsTDCfg_Tpl3, BCC_CHAIN_ADDR, BCC_Device_Addr, MC33775_PRMM_APP_VC0_OFFSET, 19, &RawData[0]); if(Status != E_OK) { CMU_ErrorStatusDevice[BCC_Device_Addr-1] = ERROR_CMU_READ_MEASUREMENTS_E2E_EXTRACT; return ERROR_CMU_READ_MEASUREMENTS_E2E_EXTRACT; } /* Extract VC for each device */ Status = Cmu_MeasLog(&RawData[0], BCC_775A_CELL, BCC_CELL_CNT, BCC_Device_Addr); Status |= Cmu_MeasLog(&RawData[14], BCC_775A_VMODULE, 1, BCC_Device_Addr); Status |= Cmu_MeasLog(&RawData[15], BCC_775A_PRMM_AINX, 4, BCC_Device_Addr); for(uint8 VcIndx = 0; VcIndx<14; VcIndx++) { Status = Bcc_775a_SL_SaM_CheckSMe3(&Bcc775aSLSaMPrimaryCfgSet_0, RawData[VcIndx]); if(Status == E_CHECK_FAILED_U8) { /*Stop at first fail and break*/ BmsState = STATE_SAFE_OV_UV_DETECTED_ON_PRIMARY_CELLS; break; } else if(Status == E_REGISTER_LOGICAL_HIGH_U8) { BmsState = STATE_SAFE_MAX_UV_DETECTED_ON_PRIMARY_CELLS; break; } else { if(BmsState != STATE_SAFE_CHAIN_BROKEN) { BmsState = STATE_RUNNING; } if(Status == E_NOT_OK) { return ERROR_CMU_READ_MEASUREMENTS_SME3_ERROR; } } } } else if((MeasChain == BCC_775A_MSR_CHAIN_SECONDARY ) && (MeasType == BCC_775A_MSR_TYPE_APPLICATION)) { Status = Bms_TPL3_SL_E2E_ExtractData(&BmsTDCfg_Tpl3, BCC_CHAIN_ADDR, BCC_Device_Addr, MC33775_SECM_APP_AIN4_OFFSET, 4, &RawData[0]); Status |= Cmu_MeasLog(&RawData[0], BCC_775A_SEC_AINX, 4, BCC_Device_Addr); if(Status != E_OK) { return ERROR_CMU_READ_MEASUREMENTS_E2E_EXTRACT; } } else { /* Do nothing */ } /* Call Bms_TD_Clear */ Status |= Bms_TD_Clear(&BmsTDCfg_Tpl3); } CalcPackVoltage(); return NO_ERROR; } /** * @brief Detection of main chain disruption * @details Defines if the main chain was cut and gets the disruption location * * @param[in] chain Chain to analyze * @param[in] numberOfDevices Number of devices connected to the main chain * @param[inout] pDeviceError Communication error tracker * @param[inout] brokenLocation Location of the chain disruption, if any * * @return HVBMS_Errors The latest error that occurred in the BMS system */ bool BrokenChainDetection(uint8 chain, uint8 numberOfDevices, uint8* pDeviceError, uint8* brokenLocation) { #define T_BCC_DEVICE_ADDR_BASE 1 volatile Std_ReturnType Status = E_NOT_OK; bool isChainBroken = false; uint8 detectionFlag = 0; uint16 sysver = 0; volatile uint8 DevIdx; Status = Bms_TD_Clear(&BmsTDCfg_Tpl3); for(DevIdx = T_BCC_DEVICE_ADDR_BASE; DevIdx <= numberOfDevices; DevIdx++) { Status = Bcc_775a_COM_ReadRegisters(chain,DevIdx,MC33775_SYS_VERSION_OFFSET,1,&BmsTDCfg_Tpl3); Status |= Bms_TPL3_SL_E2E_LogDeviceRequest(&BmsTPL3SLE2EConfig,SequenceId,BCC_CHAIN_ADDR,DevIdx); } Status |= Bms_TD_Send(&BmsTDCfg_Tpl3, &PhyError); Td_Wait(&BmsTDCfg_Tpl3); if(BmsTDCfg_Tpl3.PhyTD->Status != PHY_TS_FINISHED && Status == E_OK) { Status = Bms_TPL3_SL_E2E_Check(&BmsTPL3SLE2EConfig, &BmsTDCfg_Tpl3, SequenceId, &checkResult); if(Status != E_OK) { for(DevIdx = T_BCC_DEVICE_ADDR_BASE; DevIdx <= numberOfDevices; DevIdx++) { /* Extract requested data and detect what devices are responding */ Status = Bms_TPL3_SL_E2E_ExtractData(&BmsTDCfg_Tpl3, BCC_CHAIN_ADDR, DevIdx, MC33775_SYS_VERSION_OFFSET, 1, &sysver); if(Status !=E_OK) { *(pDeviceError+DevIdx)=1; } else { *(pDeviceError+DevIdx)=0; } } /* Detection step */ for(DevIdx = T_BCC_DEVICE_ADDR_BASE; DevIdx <= numberOfDevices; DevIdx++) { if(*(pDeviceError+DevIdx)!=*(pDeviceError+DevIdx-1)) { detectionFlag++; *brokenLocation = DevIdx; } } if(detectionFlag == 1) { isChainBroken = true; /* Enable Madd on devices */ for (DevIdx = T_BCC_DEVICE_ADDR_BASE; DevIdx <= numberOfDevices; DevIdx++) { if(*(pDeviceError+DevIdx) == 1) { Status=Bcc_775a_SetMADD(BCC_CHAIN_ADDR,DevIdx,true); } } } } } Status = Bms_TD_Clear(&BmsTDCfg_Tpl3); return isChainBroken; } #ifdef __cplusplus } #endif /** @} */