/************************************************************************ Project: Welling Motor Control Paltform Filename: alarm.c Partner Filename: alarm.h Description: System fault detection and diagnosis Complier: IAR Embedded Workbench for ARM 7.80, IAR Systems. CPU TYPE : GD32F3x0 ************************************************************************* Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd. All rights reserved. ************************************************************************* ************************************************************************* Revising History (ECL of this file): ************************************************************************/ /************************************************************************ Beginning of File, do not put anything above here except notes Compiler Directives: *************************************************************************/ #ifndef _ALARM_C_ #define _ALARM_C_ #endif /************************************************************************ Included File: *************************************************************************/ #include "syspar.h" #include "user.h" #include "FSM_1st.h" #include "FSM_2nd.h" #include "spdctrFSM.h" #include "api.h" #include "sys_ctrl.h" #ifndef RUN_ARCH_SIM #include "gd32f30x.h" #endif /************************************************************************ Private Variables: ************************************************************************/ static UWORD alm_pvt_uwResPwrWt = 0; static BOOL alm_pvt_blIPMOTReCheckFlg = FALSE; static SWORD alm_pvt_swSpdRefAbsPu = 0; static SWORD alm_pvt_swSpdFbAbsPu = 0; static SLONG alm_pvt_slSpdFbLpfAbsPu = 0; static SWORD alm_pvt_swSpdFbLpfAbsPu = 0; static SWORD alm_pvt_swIqRefAbsPu = 0; static SLONG alm_pvt_slIqRefLpfAbsPu = 0; static SWORD alm_pvt_swIqRefLpfAbsPu = 0; static BOOL alm_pvt_blTbcFirstFlg = FALSE; static BOOL alm_pvt_blTbsFirstFlg = FALSE; static SWORD alm_pvt_swRtLockPwrRatio = 0; /************************************************************************ Constant Table: *************************************************************************/ /************************************************************************ Exported Functions: *************************************************************************/ /*************************************************************** Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: ****************************************************************/ void alm_voInit(void) { alm_unCode.all = 0; alm_unBikeCode.all = 0; alm_unAction.all = 0; alm_enFSMStatus = Alm_Stop; alm_uwRotorLockedResetCnts = 0; alm_uwOSResetCnts = 0; alm_uwIPMOCResetCnts = 0; alm_uwOCResetCnts = 0; alm_pvt_blIPMOTReCheckFlg = FALSE; alm_blPowerDownFlg = FALSE; /* Clear stop count */ alm_stStopCt.ulThrPhsShrtFrcCnt = 0; alm_stStopCt.ulPWMOffCnt = 0; alm_stStopCt.ulThrPhsShrtCnt = 0; alm_stStopCt.ulRotorStopCnt = 0; alm_stStopCt.ulPWMOffShrtSwCnt = 0; alm_stStopCt.ulShrtPWMOffSwCnt = 0; alm_stStopCt.ulBikePWMOffCnt = 0; /* Clear recover count */ alm_stRecCt.ulGlbl = 0; alm_stRecCt.ulOvrVlt = 0; alm_stRecCt.ulOvrVlt1 = 0; alm_stRecCt.ulUndrVlt = 0; alm_stRecCt.ulUndrVlt1 = 0; alm_stRecCt.ulIPMOvrHeat = 0; alm_stRecCt.ulIPMOvrHeat1 = 0; alm_stRecCt.ulIPMOC = 0; alm_stRecCt.ulBikeGlbl = 0; alm_stRecCt.ulBikeSpdFlt = 0; alm_stRecCt.ulCadenceFlt = 0; alm_stRecCt.ulTorqFlt = 0; alm_stRecCt.ulThrottleFlt = 0; alm_stRecCt.ulPCBNTCFlt = 0; alm_stRecCt.ulMotorNTCFlt = 0; /* Clear alarm flag */ alm_blAlmOccrFlg = FALSE; alm_blAlmSingleRecordDoneFlg = FALSE; /* Clear alarm count */ alm_stDecCt.ulIPMOvrHeat = 0; alm_stDecCt.ulIPMOvrHeat1 = 0; alm_stDecCt.ulOvrCur = 0; alm_stDecCt.ulOvrSpd = 0; alm_stDecCt.ulOvrVltLvl1 = 0; alm_stDecCt.ulOvrVltLvl2 = 0; alm_stDecCt.ulOvrVltLvl3 = 0; alm_stDecCt.ulPhsALoss = 0; alm_stDecCt.ulPhsBLoss = 0; alm_stDecCt.ulPhsCLoss = 0; alm_stDecCt.slRotorLock = 0; alm_stDecCt.ulUndrVltLvl1 = 0; alm_stDecCt.ulUndrVltLvl2 = 0; alm_stDecCt.uwBikeSpdFlt = 0; alm_stDecCt.uwCadenceFlt = 0; alm_stDecCt.uwTorqFlt = 0; alm_stDecCt.uwThrottleFlt = 0; alm_stDecCt.uwPCBNTCFlt = 0; alm_stDecCt.uwMotorNTCFlt = 0; } /*************************************************************** Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: ****************************************************************/ void alm_voCoef(void) { alm_stDetectTbcCoefIn.uwIbAp = IBASE; alm_stDetectTbcCoefIn.uwUbVt = VBASE; alm_stDetectTbcCoefIn.uwFTbcHz = FTBC_HZ; alm_stDetectTbcCoefIn.uwPairs = cp_stMotorPara.swMotrPolePairs; alm_stDetectTbcCoefIn.uwMtRsOm = cp_stMotorPara.swRsOhm; alm_stDetectTbcCoefIn.uwFbHz = FBASE; alm_stDetectTbcCoefIn.uwOvrCurIa = cp_stControlPara.swAlmOverCurrentVal; alm_stDetectTbcCoefIn.uwOvrCurTu = cp_stControlPara.swAlmOverCurrentTM; alm_stDetectTbcCoefIn.uwAdcDetHigVt = cp_stControlPara.swAlmAdcDetectHighVal; alm_stDetectTbcCoefIn.uwAdcDetLowVt = cp_stControlPara.swAlmAdcDetectLowVal; alm_stDetectTbcCoefIn.uwPhsLossVt = cp_stControlPara.swAlmPhsLossVal; alm_stDetectTbcCoefIn.uwPhsLossTs = cp_stControlPara.swAlmPhsLossTM; alm_stDetectTbcCoefIn.uwRotorLockSpdK = cp_stControlPara.swAlmRotorLockK; alm_stDetectTbcCoefIn.uwRotorLockTs = cp_stControlPara.swAlmRotorLockTM; alm_stDetectTbcCoefIn.swIqRefLpfAbsAp = cp_stControlPara.swAlmRotorLockCurVal; alm_stDetectTbcCoefIn.swSpdFbLpfAbsRpm = cp_stControlPara.swAlmRotorLockSpdVal; alm_voDetecTBCCoef(&alm_stDetectTbcCoefIn, &alm_stDetectTbcCoef); alm_stDetectTbsCoefIn.uwPairs = cp_stMotorPara.swMotrPolePairs; alm_stDetectTbsCoefIn.uwFbHz = FBASE; alm_stDetectTbsCoefIn.uwFTbsHz = FTBS_HZ; alm_stDetectTbsCoefIn.uwUbVt = VBASE; alm_stDetectTbsCoefIn.uwOvrVlt1Vt = cp_stControlPara.swAlmOverVolVal1; alm_stDetectTbsCoefIn.uwOvrVlt2Vt = cp_stControlPara.swAlmOverVolVal2; alm_stDetectTbsCoefIn.uwOvrVlt3Vt = cp_stControlPara.swAlmOverVolVal3; alm_stDetectTbsCoefIn.uwOvrVlt1Ts = cp_stControlPara.swAlmOverVolTM1; alm_stDetectTbsCoefIn.uwOvrVlt2Tm = cp_stControlPara.swAlmOverVolTM2; alm_stDetectTbsCoefIn.uwOvrVlt3Tm = cp_stControlPara.swAlmOverVolTM3; alm_stDetectTbsCoefIn.uwUndrVlt1Vt = cp_stControlPara.swAlmUnderVolVal1; alm_stDetectTbsCoefIn.uwUndrVlt2Vt = cp_stControlPara.swAlmUnderVolVal2; alm_stDetectTbsCoefIn.uwUndrVlt1Ts = cp_stControlPara.swAlmUnderVolTM1; alm_stDetectTbsCoefIn.uwUndrVlt2Tm = cp_stControlPara.swAlmUnderVolTM2; alm_stDetectTbsCoefIn.uwOvrSpdRpm = cp_stControlPara.swAlmOverSpdVal; alm_stDetectTbsCoefIn.uwOvrSpdTm = cp_stControlPara.swAlmOverSpdTM; alm_stDetectTbsCoefIn.uwIpmOvrHeatRecCe = cp_stControlPara.swAlmRecOHeatVal; alm_stDetectTbsCoefIn.uwIpmOvrHeatTs = cp_stControlPara.swAlmOverHeatTM; alm_stDetectTbsCoefIn.uwIpmOvrHeatCe = cp_stControlPara.swAlmOverHeatCeVal; alm_voDetecTBSCoef(&alm_stDetectTbsCoefIn, &alm_stDetectTbsCoef); alm_stStopTbcCoefIn.uwIbAp = IBASE; alm_stStopTbcCoefIn.uwUbVt = VBASE; alm_stStopTbcCoefIn.uwFTbcHz = FTBC_HZ; alm_stStopTbcCoefIn.uwThrPhsShrtFrcTs = cp_stControlPara.swAlmThrPhsShrtFrcTM; alm_stStopTbcCoefIn.uwIPMOverCurStopTs = cp_stControlPara.swAlmIPMOverCurStopTM; alm_stStopTbcCoefIn.uwPwmoffShrt1SwTs = cp_stControlPara.swAlmPWMOffShrtsw1TM; alm_stStopTbcCoefIn.uwShrtPwmoffSwTs = cp_stControlPara.swAlmShrtPWMOffswTM; alm_stStopTbcCoefIn.uwPwmOffTs = cp_stControlPara.swAlmPWMOffTM; alm_stStopTbcCoefIn.uwThrPhsShrtTs = cp_stControlPara.swAlmThrPhsShrtNormTM; alm_stStopTbcCoefIn.uwOvrVlt1Vt = cp_stControlPara.swAlmOverVolVal1; alm_voStopTBCCoef(&alm_stStopTbcCoefIn, &alm_stStopTbcCoef); alm_stResetCoefIn.uwUbVt = VBASE; alm_stResetCoefIn.uwFTbcHz = FTBC_HZ; alm_stResetCoefIn.uwRecAllTs = cp_stControlPara.swAlmRecAllTM; alm_stResetCoefIn.uwIpmOcRecTs = cp_stControlPara.swAlmRecOCTM; alm_stResetCoefIn.uwOvrVltRecVt = cp_stControlPara.swAlmRecOVVal; alm_stResetCoefIn.uwOvrVltRecTs = cp_stControlPara.swAlmRecOVTM; alm_stResetCoefIn.uwOvrVltRec1Ts = cp_stControlPara.swAlmRecOVTM1; alm_stResetCoefIn.uwUndrVltRecVt = cp_stControlPara.swAlmRecUVVal; alm_stResetCoefIn.uwUndrVltRecTs = cp_stControlPara.swAlmRecUVTM; alm_stResetCoefIn.uwUndrVltRec1Ts = cp_stControlPara.swAlmRecUVTM1; alm_stResetCoefIn.uwIpmOvrHeatRecCe = cp_stControlPara.swAlmRecOHeatVal; alm_stResetCoefIn.uwIpmOvrHeatRecTs = cp_stControlPara.swAlmRecOHeatTM; alm_stResetCoefIn.uwIpmOvrHeatRec1Ts = cp_stControlPara.swAlmRecOHeatTM1; alm_voResetCoef(&alm_stResetCoefIn, &alm_stResetCoef); alm_stDetect200MSCoefIn.swMotorSpdMinRpm = ALM_MOTORSPD_MIN_RPM; alm_stDetect200MSCoefIn.uwBikeSpdFltTs = ALM_BIKESPD_FLT_TS; alm_stDetect200MSCoefIn.uwCadenceFltTs = ALM_CADENCE_FLT_TS; alm_stDetect200MSCoefIn.uwFbHz = FBASE; alm_stDetect200MSCoefIn.uwFT200MSHz = 5 ; alm_stDetect200MSCoefIn.uwMotorNTCFltTs = ALM_MOTORNTC_FLT_TS; alm_stDetect200MSCoefIn.uwPairs = cp_stMotorPara.swMotrPolePairs; alm_stDetect200MSCoefIn.uwPCBNTCFltTs = ALM_PCBNTC_FLT_TS; alm_stDetect200MSCoefIn.uwThrottleFltTs = ALM_THROTTLE_FLT_TS; alm_stDetect200MSCoefIn.uwTorqFltTs = ALM_TORQ_FLT_TS; alm_stDetect200MSCoefIn.uwTorqMaxVol = ALM_TORQ_MAX_VOL; alm_stDetect200MSCoefIn.uwTorqMinVol = ALM_TORQ_MIN_VOL; alm_stDetect200MSCoefIn.uwThrottleMaxVol = ALM_THROTTLE_MAX_VOL; alm_stDetect200MSCoefIn.uwThrottleMinVol =ALM_THROTTLE_MIN_VOL; alm_stDetect200MSCoefIn.uwNTCMaxVol = ALM_NTC_MAX_VOL; alm_stDetect200MSCoefIn.uwNTCMinVol = ALM_NTC_MIN_VOL; alm_voDetec200MSCoef(&alm_stDetect200MSCoefIn, &alm_stDetect200MSCoef); alm_stReset1MSCoefIn.uwBikeGlblTm = ALM_BIKE_REC_ALL_TM; alm_stReset1MSCoefIn.uwBikeSpdFltTm = ALM_BIKESPD_REC_TM; alm_stReset1MSCoefIn.uwCadenceFltTm = ALM_CADENCE_REC_TM; alm_stReset1MSCoefIn.uwFT1MSHz = 1000; alm_stReset1MSCoefIn.uwMotorNTCFltTm = ALM_MOTORNTC_REC_TM; alm_stReset1MSCoefIn.uwPCBNTCFltTm = ALM_PCBNTC_REC_TM; alm_stReset1MSCoefIn.uwThrottleFltTm = ALM_THROTTLE_REC_TM; alm_stReset1MSCoefIn.uwTorqFltTm = ALM_TORQ_REC_TM; alm_voReset1MSCoef(&alm_stReset1MSCoefIn, &alm_stReset1MSCoef); } /*************************************************************** Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: ****************************************************************/ void alm_voDetecTBCCoef(ALM_DETECTBC_COFIN *in, ALM_DETECTBC_COF *out) { UWORD uwRbOm; if (in->uwIbAp < 1) { in->uwIbAp = 1; } if (in->uwFbHz < 1) { in->uwFbHz = 1; } uwRbOm = (UWORD)((ULONG)in->uwUbVt * 100000 / in->uwIbAp); /* unit: 0.01Ohm, Resistance base */ out->uwRsPu = (UWORD)(((ULONG)in->uwMtRsOm << 15) / uwRbOm); /* Q15, Phase resistance */ out->uwPbWt = (UWORD)((ULONG)in->uwUbVt * in->uwIbAp * 3 / 100 >> 1); /* unit: 0.1w, Power base */ out->ulOvrCurValPu = ((ULONG)in->uwOvrCurIa << 14) / in->uwIbAp; // CUR_AP2PU(x) (((ULONG)(x)<<14)/IBASE) Q14 out->ulOvrCurValCt = ((ULONG)in->uwOvrCurTu * in->uwFTbcHz / 1000000) >> 1; // TBC_US2CT(x) ((ULONG)(x)*FTBC_HZ/1000000) out->slAdcDetHigValPu = (SLONG)in->uwAdcDetHigVt * 4096 / 330; //_IQ12(A) (SLONG)(A * 4096L) out->slAdcDetLowValPu = (SLONG)in->uwAdcDetLowVt * 4096 / 330; out->ulPhsLossValPu = ((ULONG)in->uwPhsLossVt << 14) / in->uwIbAp; out->ulPhsLossValCt = ((ULONG)in->uwPhsLossTs * in->uwFTbcHz) >> 1; // TBC_S2CT(x) ((ULONG)(x)*FTBC_HZ) out->slRotorLockSpdK = (SLONG)in->uwRotorLockSpdK * 1024 / 100; //_IQ10(0.5) (SLONG)(A * 1024L) out->slRotorLockValCt = ((SLONG)in->uwRotorLockTs * in->uwFTbcHz) >> 1; out->slIqRefLpfAbsValPu = ((SLONG)in->swIqRefLpfAbsAp << 14) / in->uwIbAp; // CUR_AP2PU(x) (((ULONG)(x)<<14)/IBASE) out->slSpdFbLpfAbsValPu = ((SLONG)in->swSpdFbLpfAbsRpm << 15) / 60 * in->uwPairs / in->uwFbHz; } /*************************************************************** Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: ****************************************************************/ void alm_voDetecTBC(const ALM_IN *in, const ALM_DETECTBC_COF *coef) { SWORD swTmp1, swTmp2; if(clasB_unFaultCode.all != 0) //MicroFault Handle { alm_unAction.bit.PWMOff = 1; alm_unCode.bit.MCUErr = 1; } /*======================================================================= IPM fault =======================================================================*/ if (iPwm_GetBreakState(0) != 0) { alm_unAction.bit.ThrPhsShrtFrc = 1; alm_unCode.bit.IPMFlt = 1; } if (alm_pvt_blTbcFirstFlg == TRUE) { /*======================================================================= Software Over current =======================================================================*/ if (in->blADCInitOvrFlg) { if (curSpeed_state.state != Stop) { if (in->uwIpeakPu > coef->ulOvrCurValPu) // 9A { alm_stDecCt.ulOvrCur++; if (alm_stDecCt.ulOvrCur >= coef->ulOvrCurValCt) // 500us { alm_stDecCt.ulOvrCur = coef->ulOvrCurValCt; alm_unAction.bit.PWMOff = 1; alm_unCode.bit.OvrCur = 1; } } else { alm_stDecCt.ulOvrCur = 0; } } else { alm_stDecCt.ulOvrCur = 0; } } /*======================================================================= ADC Self Detecting Fault =======================================================================*/ // if (in->blADCInitOvrFlg) // { // if((in->uwIdcOffset >= coef->slAdcDetHigValPu)||(in->uwIdcOffset <= coef->slAdcDetLowValPu)) // { // alm_unAction.bit.ThrPhsShrt = 1; // alm_unCode.bit.ADCOffsetFlt = 1; // } // } /*======================================================================= Over load =======================================================================*/ /*======================================================================= Phase loss =======================================================================*/ if (curSpeed_state.state != Stop) { if (scm_swIqRefPu > 150 || scm_swIqRefPu < -150) { if (in->uwIaAbsPu < coef->ulPhsLossValPu) // 0.18A { alm_stDecCt.ulPhsALoss++; } else { alm_stDecCt.ulPhsALoss = 0; } if (in->uwIbAbsPu < coef->ulPhsLossValPu) { alm_stDecCt.ulPhsBLoss++; } else { alm_stDecCt.ulPhsBLoss = 0; } if (in->uwIcAbsPu < coef->ulPhsLossValPu) { alm_stDecCt.ulPhsCLoss++; } else { alm_stDecCt.ulPhsCLoss = 0; } } if (alm_stDecCt.ulPhsALoss >= coef->ulPhsLossValCt || alm_stDecCt.ulPhsBLoss >= coef->ulPhsLossValCt || alm_stDecCt.ulPhsCLoss >= coef->ulPhsLossValCt) // 4s { alm_stDecCt.ulPhsALoss = coef->ulPhsLossValCt; alm_stDecCt.ulPhsBLoss = coef->ulPhsLossValCt; alm_stDecCt.ulPhsCLoss = coef->ulPhsLossValCt; alm_unAction.bit.PWMOff = 1; // alm_unAction.bit.ThrPhsShrt = 1; // alm_unCode.bit.PhsLoss = 1; } } else { alm_stDecCt.ulPhsALoss = 0; alm_stDecCt.ulPhsBLoss = 0; alm_stDecCt.ulPhsCLoss = 0; } /*======================================================================= Set AlmTbcDetectFlg =======================================================================*/ alm_pvt_blTbcFirstFlg = FALSE; } else { /*======================================================================= Rotor lock for sensorless =======================================================================*/ alm_pvt_swSpdRefAbsPu = (SWORD)in->uwSpdRefAbsPu; // Q15 alm_pvt_swIqRefAbsPu = (SWORD)ABS(in->swIqRefPu); alm_pvt_slIqRefLpfAbsPu = (SLONG)0x0010 * (alm_pvt_swIqRefAbsPu - alm_pvt_swIqRefLpfAbsPu) + alm_pvt_slIqRefLpfAbsPu; // Q30 alm_pvt_swIqRefLpfAbsPu = (SWORD)(alm_pvt_slIqRefLpfAbsPu >> 15); alm_pvt_swSpdFbAbsPu = (SWORD)in->uwSpdFbkLpfAbsPu; // Q15 alm_pvt_slSpdFbLpfAbsPu = (SLONG)0x0010 * (alm_pvt_swSpdFbAbsPu - alm_pvt_swSpdFbLpfAbsPu) + alm_pvt_slSpdFbLpfAbsPu; // Q30 alm_pvt_swSpdFbLpfAbsPu = (SWORD)(alm_pvt_slSpdFbLpfAbsPu >> 15); // Q15 if (((curSpeed_state.state == ClzLoop) || (curSpeed_state.state == StartUp)) && (in->uwSpdRefAbsPu > 0)) { swTmp1 = (in->swIalhpaPu * in->swIalhpaPu + in->swIbetaPu * in->swIbetaPu) >> 14; // Q14=Q14+Q14-Q14 swTmp2 = (SWORD)(swTmp1 * (SLONG)coef->uwRsPu >> 14); // Q15=Q14+Q15-Q14 alm_pvt_uwResPwrWt = swTmp2 * coef->uwPbWt >> 15; // unit: 0.1w if ((in->swMotorPwrInWt > 0) && (alm_pvt_swIqRefLpfAbsPu > coef->slIqRefLpfAbsValPu) && (alm_pvt_swSpdFbLpfAbsPu < coef->slSpdFbLpfAbsValPu)) { alm_pvt_swRtLockPwrRatio = (SWORD)((SLONG)alm_pvt_uwResPwrWt * 100 / in->swMotorPwrInWt); if (alm_pvt_uwResPwrWt > (coef->slRotorLockSpdK * in->swMotorPwrInWt >> 10)) // k = 0.5 { alm_stDecCt.slRotorLock++; if (alm_stDecCt.slRotorLock >= coef->slRotorLockValCt) // 4s { alm_stDecCt.slRotorLock = coef->slRotorLockValCt; // alm_unAction.bit.ThrPhsShrt = 1; alm_unAction.bit.PWMOff = 1; alm_unCode.bit.RotorLock = 1; } } else { alm_stDecCt.slRotorLock--; if (alm_stDecCt.slRotorLock < 0) { alm_stDecCt.slRotorLock = 0; } } } else { alm_stDecCt.slRotorLock = 0; } } else { alm_stDecCt.slRotorLock = 0; } /*======================================================================= Spi Theta Fault =======================================================================*/ if(in->blSpiThetaFltFlg) { alm_unAction.bit.PWMOff = 1; alm_unCode.bit.SpiThetaFlt = 1; } /*======================================================================= Set AlmTbcDetectFlg =======================================================================*/ alm_pvt_blTbcFirstFlg = TRUE; } /*========================== Alarm flag set ===========================*/ if ((alm_unCode.all != 0) || (alm_pvt_blIPMOTReCheckFlg == TRUE) || (alm_unBikeCode.all != 0)) { alm_blAlmOccrFlg = TRUE; } } /*************************************************************** Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: ****************************************************************/ void alm_voDetecTBSCoef(ALM_DETECTBS_COFIN *in, ALM_DETECTBS_COF *out) { if (in->uwFbHz < 1) { in->uwFbHz = 1; } if (in->uwUbVt < 1) { in->uwUbVt = 1; } out->ulOvrVltLvl1ValPu = ((ULONG)in->uwOvrVlt1Vt << 14) / in->uwUbVt; out->ulOvrVltLvl2ValPu = ((ULONG)in->uwOvrVlt2Vt << 14) / in->uwUbVt; out->ulOvrVltLvl3ValPu = ((ULONG)in->uwOvrVlt3Vt << 14) / in->uwUbVt; out->ulOvrVltLvl1ValCt = ((ULONG)in->uwOvrVlt1Ts * in->uwFTbsHz) >> 1; // TBS_S2CT(x) ((ULONG)(x)*FTBS_HZ) out->ulOvrVltLvl2ValCt = ((ULONG)in->uwOvrVlt2Tm * in->uwFTbsHz / 1000) >> 1; out->ulOvrVltLvl3ValCt = ((ULONG)in->uwOvrVlt3Tm * in->uwFTbsHz / 1000) >> 1; out->ulUndrVltLvl1ValPu = ((ULONG)in->uwUndrVlt1Vt << 14) / in->uwUbVt; out->ulUndrVltLvl2ValPu = ((ULONG)in->uwUndrVlt2Vt << 14) / in->uwUbVt; out->ulUndrVltLvl1ValCt = ((ULONG)in->uwUndrVlt1Ts * in->uwFTbsHz) >> 1; out->ulUndrVltLvl2ValCt = ((ULONG)in->uwUndrVlt2Tm * in->uwFTbsHz / 1000) >> 1; // TBS_MS2CT(x) ((ULONG)(x)*FTBS_HZ/1000) out->slOvrSpdValPu = ((SLONG)in->uwOvrSpdRpm << 15) / 60 * in->uwPairs / in->uwFbHz; // SPD_RPM2PU(x) (((SLONG)(x)<<15)/60*MOTOR_PAIRS/FBASE) /* rpm to Pu(Q15) */ out->ulOvrSpdValCt = ((ULONG)in->uwOvrSpdTm * in->uwFTbsHz / 1000) >> 1; out->uwIPMOvrHeatRecValCe = in->uwIpmOvrHeatRecCe; out->ulIPMOvrHeatValCt = ((ULONG)in->uwIpmOvrHeatTs * in->uwFTbsHz) >> 1; out->uwIPMOvrHeatValCe = in->uwIpmOvrHeatCe; } /*************************************************************** Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: ****************************************************************/ void alm_voDetecTBS(const ALM_IN *in, const ALM_DETECTBS_COF *coef) { if (alm_pvt_blTbsFirstFlg == FALSE) { /*======================================================================= Over voltage =======================================================================*/ /* Over voltage level 3 */ if (in->uwVdcPu > coef->ulOvrVltLvl3ValPu) // 45V { alm_stDecCt.ulOvrVltLvl3++; if (alm_stDecCt.ulOvrVltLvl3 >= coef->ulOvrVltLvl3ValCt) // 1ms { alm_stDecCt.ulOvrVltLvl3 = coef->ulOvrVltLvl3ValCt; // alm_unAction.bit.ThrPhsShrt = 1; alm_unCode.bit.OvrVlt = 1; alm_unAction.bit.PWMOff = 1; } } else { alm_stDecCt.ulOvrVltLvl3 = 0; } /* Over voltage level 2 */ if (in->uwVdcPu > coef->ulOvrVltLvl2ValPu) // 44V { alm_stDecCt.ulOvrVltLvl2++; if (alm_stDecCt.ulOvrVltLvl2 >= coef->ulOvrVltLvl2ValCt) // 10ms { alm_stDecCt.ulOvrVltLvl2 = coef->ulOvrVltLvl2ValCt; // alm_unAction.bit.ThrPhsShrt = 1; alm_unCode.bit.OvrVlt = 1; alm_unAction.bit.PWMOff = 1; } } else { alm_stDecCt.ulOvrVltLvl2 = 0; } /* Over voltage level 1 */ if (in->uwVdcPu > coef->ulOvrVltLvl1ValPu) // 43V { alm_stDecCt.ulOvrVltLvl1++; if (alm_stDecCt.ulOvrVltLvl1 >= coef->ulOvrVltLvl1ValCt) // 2s { alm_stDecCt.ulOvrVltLvl1 = coef->ulOvrVltLvl1ValCt; // alm_unAction.bit.ThrPhsShrt = 1; alm_unCode.bit.OvrVlt = 1; alm_unAction.bit.PWMOff = 1; } } else { alm_stDecCt.ulOvrVltLvl1 = 0; } /*======================================================================= Under voltage =======================================================================*/ /* Under voltage level 2 */ if (in->uwVdcCompPu < coef->ulUndrVltLvl2ValPu) // 160v { alm_stDecCt.ulUndrVltLvl2++; if (alm_stDecCt.ulUndrVltLvl2 >= coef->ulUndrVltLvl2ValCt) // 1ms { alm_stDecCt.ulUndrVltLvl2 = coef->ulUndrVltLvl2ValCt; alm_unAction.bit.PWMOff = 1; alm_unCode.bit.UndrVlt = 1; } } else { alm_stDecCt.ulUndrVltLvl2 = 0; } // /* Under voltage level 1 */ if (in->uwVdcCompPu < coef->ulUndrVltLvl1ValPu) // 190V { alm_stDecCt.ulUndrVltLvl1++; if (alm_stDecCt.ulUndrVltLvl1 >= coef->ulUndrVltLvl1ValCt) // 2s { alm_stDecCt.ulUndrVltLvl1 = coef->ulUndrVltLvl1ValCt; alm_unAction.bit.PWMOff = 1; alm_unCode.bit.UndrVlt = 1; } } else { alm_stDecCt.ulUndrVltLvl1 = 0; } alm_pvt_blTbsFirstFlg = TRUE; } else { /*======================================================================= Over speed =======================================================================*/ if (in->uwSpdFbkLpfAbsPu > coef->slOvrSpdValPu) // 19000rpm { alm_stDecCt.ulOvrSpd++; if (alm_stDecCt.ulOvrSpd >= coef->ulOvrSpdValCt) // 100ms { alm_stDecCt.ulOvrSpd = coef->ulOvrSpdValCt; alm_unAction.bit.ThrPhsShrt = 1; alm_unCode.bit.OvrSpd = 1; } } else { alm_stDecCt.ulOvrSpd = 0; } /*======================================================================= over heat =======================================================================*/ if (alm_pvt_blIPMOTReCheckFlg == TRUE) { if (in->uwIPMTempCe > coef->uwIPMOvrHeatRecValCe) // 70 { alm_stDecCt.ulIPMOvrHeat1++; if (alm_stDecCt.ulIPMOvrHeat1 >= coef->ulIPMOvrHeatValCt) // 2s { alm_stDecCt.ulIPMOvrHeat1 = coef->ulIPMOvrHeatValCt; // alm_unAction.bit.ThrPhsShrt = 1; alm_unAction.bit.PWMOff = 1; alm_unCode.bit.IPMOvrHeat = 1; } } else { alm_stDecCt.ulIPMOvrHeat1 = 0; } } else { if (in->uwIPMTempCe > coef->uwIPMOvrHeatValCe) // 85 { alm_stDecCt.ulIPMOvrHeat++; if (alm_stDecCt.ulIPMOvrHeat >= coef->ulIPMOvrHeatValCt) // 2s { alm_stDecCt.ulIPMOvrHeat = coef->ulIPMOvrHeatValCt; // alm_unAction.bit.ThrPhsShrt = 1; alm_unAction.bit.PWMOff = 1; alm_unCode.bit.IPMOvrHeat = 1; alm_pvt_blIPMOTReCheckFlg = TRUE; } } else { alm_stDecCt.ulIPMOvrHeat = 0; } } /*======================================================================= Hall loss // MPS position loss =======================================================================*/ // cp_stHistoryPara.uwPosSensorAlamTimes++; /*======================================================================= Communication over time =======================================================================*/ // if (uart_bCommOvrTmFlg) // { // alm_unAction.bit.PWMOff = 1; // // alm_unAction.bit.ThrPhsShrt = 1; // alm_unCode.bit.CommOvrTm = 1; // } alm_pvt_blTbsFirstFlg = FALSE; } } /*************************************************************** Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: ****************************************************************/ void alm_voHandleTBC(const ALM_IN *in) { /* Alarm occur */ if (alm_blAlmOccrFlg) { /* micro fault */ if(clasB_unFaultCode.all != 0) { if(scm_stSpdFbkLpf.slY.sw.hi < SPD_RPM2PU(10))//pu? ?10rpm { NVIC_SystemReset(); } } /* Alarm handle FSM */ switch (alm_enFSMStatus) { case Alm_Stop: alm_voStopTBC(in, &alm_stStopTbcCoef); /* Stop in TBC */ if (cmfsm_stFlg.blMotorStopFlg) { sysfsm_stFlg.blFSMRstOvrFlg = FALSE; /* Enable control mode FSM reset */ sysfsm_stFlg.blCtrlMdVarClcOvrFlg = FALSE; /* Enable control mode variable clear */ alm_enFSMStatus = Alm_VarClc; } break; case Alm_VarClc: if (sysfsm_stFlg.blFSMRstOvrFlg && sysfsm_stFlg.blCtrlMdVarClcOvrFlg) { alm_enFSMStatus = Alm_Reset; } break; case Alm_Reset: alm_voReset(in, &alm_stResetCoef); break; default: break; } } } /*************************************************************** Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: ****************************************************************/ void alm_voHandleTBS(const ALM_IN *in) { /* Alarm occur */ if (alm_blAlmOccrFlg) { /* Alarm handle FSM */ switch (alm_enFSMStatus) { case Alm_Stop: // alm_voStopTBS(); /* Stop in TBS */ break; case Alm_VarClc: break; case Alm_Reset: // alm_voReset(in,&alm_stResetCoef); break; default: break; } } } /*************************************************************** Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: ****************************************************************/ void alm_voStopTBCCoef(ALM_STOPTBC_COFIN *in, ALM_STOPTBC_COF *out) { if (in->uwIbAp < 1) { in->uwIbAp = 1; } if (in->uwUbVt < 1) { in->uwUbVt = 1; } out->ulThrPhsShrtFrcValCt = ((ULONG)in->uwThrPhsShrtFrcTs * in->uwFTbcHz) / 1000; // TBC_S2CT(x) ((ULONG)(x)*FTBC_HZ) out->ulStopCurValCt = ((ULONG)in->uwIPMOverCurStopTs * in->uwFTbcHz) / 1000; out->ulPWMOffShrt1SwValCt = ((ULONG)in->uwPwmoffShrt1SwTs * in->uwFTbcHz) / 1000; out->ulShrtPWMOffSwValCt = ((ULONG)in->uwShrtPwmoffSwTs * in->uwFTbcHz) / 1000; out->ulPWMOffValCt = ((ULONG)in->uwPwmOffTs * in->uwFTbcHz) / 1000; out->ulThrPhsShrtNormValCt = ((ULONG)in->uwThrPhsShrtTs * in->uwFTbcHz) / 1000; out->ulOvrVltLvl1ValPu = (((ULONG)in->uwOvrVlt1Vt << 14) / in->uwUbVt) / 1000; } /*************************************************************** Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: ****************************************************************/ void alm_voStopTBC(const ALM_IN *in, const ALM_STOPTBC_COF *coef) { if (alm_unAction.bit.ThrPhsShrtFrc != 0) { if (iPwm_GetBreakState(0) != 0) { sysctrl_voPwmOff(); /* PWM off */ iPwm_ClearBreak(0); /* Clear TIME0 break flag */ iPwm_EnableOutput(0); /* Enable TIME0 Channel outputs */ alm_stStopCt.ulThrPhsShrtFrcCnt++; if (alm_stStopCt.ulThrPhsShrtFrcCnt > coef->ulThrPhsShrtFrcValCt) // 200ms { alm_stStopCt.ulRotorStopCnt++; if (alm_stStopCt.ulRotorStopCnt >= coef->ulStopCurValCt) // 100ms { sysctrl_voPwmOff(); /* PWM off */ cmfsm_stFlg.blMotorStopFlg = TRUE; alm_stStopCt.ulRotorStopCnt = (UWORD)coef->ulStopCurValCt; } } alm_stStopCt.ulShrtPWMOffSwCnt = 0; } else {} } else if (alm_unAction.bit.PWMOff != 0) { alm_stStopCt.ulPWMOffShrtSwCnt++; alm_stStopCt.ulPWMOffCnt++; if (alm_stStopCt.ulPWMOffShrtSwCnt < coef->ulPWMOffShrt1SwValCt) // 100ms { sysctrl_voPwmOff(); alm_stStopCt.ulRotorStopCnt = 0; } // else if(alm_stStopCt.ulPWMOffShrtSwCnt < coef->ulPWMOffShrt2SwValCt) // { // sysctrl_voThrPhsShrt(); // } else { alm_stStopCt.ulPWMOffShrtSwCnt = 0; } if (alm_stStopCt.ulPWMOffCnt > coef->ulPWMOffValCt) // 200ms { cmfsm_stFlg.blMotorStopFlg = TRUE; alm_stStopCt.ulPWMOffCnt = 0; } alm_stStopCt.ulShrtPWMOffSwCnt = 0; } else // if (alm_unAction.bit.ThrPhsShrt) { alm_stStopCt.ulShrtPWMOffSwCnt++; alm_stStopCt.ulThrPhsShrtCnt++; if (alm_stStopCt.ulShrtPWMOffSwCnt < coef->ulThrPhsShrtNormValCt) // 100ms { sysctrl_voThrPhsShrt(); /* Three phase short */ } else if (alm_stStopCt.ulShrtPWMOffSwCnt < (coef->ulThrPhsShrtNormValCt + coef->ulShrtPWMOffSwValCt)) // 100ms + 100ms { sysctrl_voPwmOff(); if (in->uwVdcPu > coef->ulOvrVltLvl1ValPu) // over vol level1 43V { alm_stStopCt.ulShrtPWMOffSwCnt = 0; } alm_stStopCt.ulRotorStopCnt = 0; } else { alm_stStopCt.ulShrtPWMOffSwCnt = 0; } if (alm_stStopCt.ulThrPhsShrtCnt > coef->ulThrPhsShrtFrcValCt) // 200ms { sysctrl_voPwmOff(); /* PWM off */ cmfsm_stFlg.blMotorStopFlg = TRUE; alm_stStopCt.ulThrPhsShrtCnt = 0; } alm_stStopCt.ulPWMOffShrtSwCnt = 0; } } /*************************************************************** Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: ****************************************************************/ void alm_voStopTBS(void) { // if (alm_unAction.bit.SlowDwn) // { // acm_voAlmCtrMdTbs(); // } } /*************************************************************** Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: ****************************************************************/ void alm_voResetCoef(ALM_RESET_COFIN *in, ALM_RESET_COF *out) { if (in->uwUbVt < 1) { in->uwUbVt = 1; } out->ulRecAllValCt = ((ULONG)in->uwRecAllTs * in->uwFTbcHz) / 1000; // TBC_S2CT(x) ((ULONG)(x)*FTBC_HZ) out->ulIPMOcRecValCt = ((ULONG)in->uwIpmOcRecTs * in->uwFTbcHz) / 1000; out->ulOvrVltRecValPu = ((ULONG)in->uwOvrVltRecVt << 14) / in->uwUbVt; out->ulOvrVltRecValCt = ((ULONG)in->uwOvrVltRecTs * in->uwFTbcHz) / 1000; out->ulOvrVltRec1ValCt = ((ULONG)in->uwOvrVltRec1Ts * in->uwFTbcHz) / 1000; out->ulUndrVltRecValPu = ((ULONG)in->uwUndrVltRecVt << 14) / in->uwUbVt; out->ulUndrVltRecValCt = ((ULONG)in->uwUndrVltRecTs * in->uwFTbcHz) / 1000; out->ulUndrVltRec1ValCt = ((ULONG)in->uwUndrVltRec1Ts * in->uwFTbcHz) / 1000; out->uwIPMOvrHeatRecValCe = in->uwIpmOvrHeatRecCe; out->ulIPMOvrHeatRecValCt = (ULONG)(in->uwIpmOvrHeatRecTs * in->uwFTbcHz); out->ulIPMOvrHeatRec1ValCt = (ULONG)(in->uwIpmOvrHeatRec1Ts * in->uwFTbcHz); } /*************************************************************** Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: ****************************************************************/ void alm_voReset(const ALM_IN *in, const ALM_RESET_COF *coef) { /*======================================================================= Recover condition =======================================================================*/ /* Recover time of global */ if (alm_stRecCt.ulGlbl < coef->ulRecAllValCt) // 200ms { alm_stRecCt.ulGlbl++; } /* Recover time of IPM OC */ if (alm_stRecCt.ulIPMOC < coef->ulIPMOcRecValCt) // 100ms { alm_stRecCt.ulIPMOC++; } /* Recover time of over voltage */ if (in->uwVdcPu < coef->ulOvrVltRecValPu) // 450v { if (alm_stRecCt.ulOvrVlt < coef->ulOvrVltRecValCt) // 100ms { alm_stRecCt.ulOvrVlt++; } alm_stRecCt.ulOvrVlt1 = 0; } else { if (alm_stRecCt.ulOvrVlt1 < coef->ulOvrVltRec1ValCt) // 150ms { alm_stRecCt.ulOvrVlt1++; } alm_stRecCt.ulOvrVlt = 0; } /* Recover time of under voltage */ if (in->uwVdcPu > coef->ulUndrVltRecValPu) // 30v { if (alm_stRecCt.ulUndrVlt < coef->ulUndrVltRecValCt) // 100ms { alm_stRecCt.ulUndrVlt++; } } else { if (alm_stRecCt.ulUndrVlt1 < coef->ulUndrVltRec1ValCt) // 150ms { // alm_stRecCt.ulUndrVlt1++; } } /* Recover time of IPM over heat */ if (in->uwIPMTempCe < coef->uwIPMOvrHeatRecValCe) // 75 { if (alm_stRecCt.ulIPMOvrHeat < coef->ulIPMOvrHeatRecValCt) // 60s { alm_stRecCt.ulIPMOvrHeat++; } alm_stRecCt.ulIPMOvrHeat1 = 0; } else { if (alm_stRecCt.ulIPMOvrHeat1 < coef->ulIPMOvrHeatRec1ValCt) // 120s { alm_stRecCt.ulIPMOvrHeat1++; } alm_stRecCt.ulIPMOvrHeat = 0; } /*======================================================================= Alarm code clear =======================================================================*/ if (alm_stRecCt.ulGlbl >= coef->ulRecAllValCt) // 200ms { /* IPM fault */ if ((alm_unCode.bit.IPMFlt == 1) && (alm_stRecCt.ulIPMOC >= coef->ulIPMOcRecValCt)) { iPwm_ClearBreak(0); /* Clear TIME0 break flag */ iPwm_EnableOutput(0); /* Enable TIME0 Channel outputs */ alm_unCode.bit.IPMFlt = 0; } /* Over current */ if (alm_unCode.bit.OvrCur != 0) { alm_stDecCt.ulOvrCur = 0; alm_unCode.bit.OvrCur = 0; } /* Over voltage */ if (alm_unCode.bit.OvrVlt != 0) { if ((alm_stRecCt.ulOvrVlt >= coef->ulOvrVltRecValCt) || (alm_stRecCt.ulUndrVlt1 >= coef->ulOvrVltRec1ValCt)) // 4s 20s { alm_stDecCt.ulOvrVltLvl1 = 0; alm_stDecCt.ulOvrVltLvl2 = 0; alm_stDecCt.ulOvrVltLvl3 = 0; alm_unCode.bit.OvrVlt = 0; } } /* Under voltage */ if (alm_unCode.bit.UndrVlt != 0) { if ((alm_stRecCt.ulUndrVlt >= coef->ulUndrVltRecValCt) || (alm_stRecCt.ulUndrVlt1 >= coef->ulUndrVltRec1ValCt)) // 4s 20s { alm_stDecCt.ulUndrVltLvl1 = 0; alm_stDecCt.ulUndrVltLvl2 = 0; alm_unCode.bit.UndrVlt = 0; } } /* IPM over heat */ if (alm_unCode.bit.IPMOvrHeat != 0) { if (alm_stRecCt.ulIPMOvrHeat >= coef->ulIPMOvrHeatRecValCt) { alm_stDecCt.ulIPMOvrHeat = 0; alm_stDecCt.ulIPMOvrHeat1 = 0; alm_unCode.bit.IPMOvrHeat = 0; alm_pvt_blIPMOTReCheckFlg = FALSE; } else if (alm_stRecCt.ulIPMOvrHeat1 >= coef->ulIPMOvrHeatRec1ValCt) { alm_stDecCt.ulIPMOvrHeat = 0; alm_stDecCt.ulIPMOvrHeat1 = 0; alm_unCode.bit.IPMOvrHeat = 0; alm_pvt_blIPMOTReCheckFlg = TRUE; } else { //do nothing } } /* Hall loss */ if (alm_unCode.bit.HallLoss != 0) { alm_unCode.bit.HallLoss = 0; } /* Spi Thete Fault */ if((alm_unCode.bit.SpiThetaFlt != 0) && (!in->blSpiThetaFltFlg)) { alm_unCode.bit.SpiThetaFlt = 0; } /* Phase loss */ if (alm_unCode.bit.PhsLoss != 0) { alm_stDecCt.ulPhsALoss = 0; alm_stDecCt.ulPhsBLoss = 0; alm_stDecCt.ulPhsCLoss = 0; alm_unCode.bit.PhsLoss = 0; } /* Rotor lock */ if (alm_unCode.bit.RotorLock != 0) { alm_stDecCt.slRotorLock = 0; alm_unCode.bit.RotorLock = 0; } /* Communication over time */ if (alm_unCode.bit.CommOvrTm != 0) { alm_unCode.bit.CommOvrTm = 0; } if (alm_unCode.bit.ADCOffsetFlt != 0) { /* ADC init */ adc_stDownOut.ulIdcRegSum = 0; adc_stDownOut.ulUaRegSum = 0; adc_stDownOut.ulUbRegSum = 0; adc_stDownOut.ulUcRegSum = 0; adc_stDownOut.uwADCCalibCt = 0; adc_stDownOut.blADCCalibFlg = FALSE; adc_stUpOut.uwADCCalibCt = 0; adc_stUpOut.blADCCalibFlg = FALSE; sysfsm_stFlg.blADCInitOvrFlg = FALSE; alm_unCode.bit.ADCOffsetFlt = 0; } } /*======================================================================= Alarm flag clear =======================================================================*/ if (alm_unCode.all==0) { /* Clear alarm action */ alm_unAction.all = 0; /* Clear stop count */ alm_stStopCt.ulThrPhsShrtFrcCnt = 0; alm_stStopCt.ulPWMOffCnt = 0; alm_stStopCt.ulThrPhsShrtCnt = 0; alm_stStopCt.ulRotorStopCnt = 0; alm_stStopCt.ulPWMOffShrtSwCnt = 0; alm_stStopCt.ulShrtPWMOffSwCnt = 0; /* Clear recover count */ alm_stRecCt.ulGlbl = 0; alm_stRecCt.ulOvrVlt = 0; alm_stRecCt.ulOvrVlt1 = 0; alm_stRecCt.ulUndrVlt = 0; alm_stRecCt.ulUndrVlt1 = 0; alm_stRecCt.ulIPMOvrHeat = 0; alm_stRecCt.ulIPMOvrHeat1 = 0; alm_stRecCt.ulIPMOC = 0; /* Clear alarm flag */ alm_blAlmOccrFlg = FALSE; alm_blAlmSingleRecordDoneFlg = FALSE; alm_blPowerDownFlg = FALSE; /* Clear speed command*/ // cmd_swSpdRefPu = 0; } } /*************************************************************** Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: ****************************************************************/ void alm_voHandleRst(void) { alm_enFSMStatus = Alm_Stop; } /*************************************************************** Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: ****************************************************************/ void alm_voDetec200MSCoef(ALM_DETEC200MS_COFIN *in, ALM_DETEC200MS_COF *out) { if (in->uwFbHz < 1) { in->uwFbHz = 1; } out->swMotorSpdMinPu = (SWORD)(((SLONG)in->swMotorSpdMinRpm << 15) / (SWORD)60 * (SWORD)in->uwPairs / (SWORD)in->uwFbHz); out->uwBikeSpdFltCt = in->uwBikeSpdFltTs * in->uwFT200MSHz; out->uwCadenceFltCt = in->uwCadenceFltTs * in->uwFT200MSHz; out->uwTorqFltCt = in->uwTorqFltTs * in->uwFT200MSHz; out->uwThrottleFltCt = in->uwThrottleFltTs * in->uwFT200MSHz; out->uwPCBNTCFltCt = in->uwPCBNTCFltTs * in->uwFT200MSHz; out->uwMotorNTCFltCt = in->uwMotorNTCFltTs * in->uwFT200MSHz; out->uwTorqMaxReg = (UWORD)((ULONG)in->uwTorqMaxVol * 4096 / 33); out->uwTorqMinReg = (UWORD)((ULONG)in->uwTorqMinVol * 4096 / 33); out->uwThrottleMaxReg = (UWORD)((ULONG)in->uwThrottleMaxVol * 4096 / 33); out->uwThrottleMinReg = (UWORD)((ULONG)in->uwThrottleMinVol * 4096 / 33); out->uwNTCMaxReg = (UWORD)((ULONG)in->uwNTCMaxVol * 4096 / 33); out->uwNTCMinReg = (UWORD)((ULONG)in->uwNTCMinVol * 4096 / 33); } /*************************************************************** Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: ****************************************************************/ void alm_voDetec200MS(const ALM_BIKE_IN *in, const ALM_DETEC200MS_COF *coef) /* parasoft-suppress METRICS-28 "本项目圈复杂度无法更改,后续避免" */ { /** Bike sensors judge each other **/ /* Bike speed sensor fault */ if(in->uwCadenceFreqPu > 0) { if(in->uwBikeSpdPu == 0) { alm_stDecCt.uwBikeSpdFlt ++; if(alm_stDecCt.uwBikeSpdFlt >= coef->uwBikeSpdFltCt) { alm_stDecCt.uwBikeSpdFlt = coef->uwBikeSpdFltCt; alm_unBikeCode.bit.BikeSpdSen = 1; alm_unAction.bit.PWMOff = 1; } } else if(in->blBikeSpdOvrFlg) { alm_unBikeCode.bit.BikeSpdSen = 1; alm_unAction.bit.PWMOff = 1; } else { alm_stDecCt.uwBikeSpdFlt = 0; } } else { alm_stDecCt.uwBikeSpdFlt = 0; } /* Bike cadence sensor fault */ if(in->uwBikeSpdPu > 0) { if(in->uwTroqPu > ass_stCalCoef.uwAssThreshold) { if(in->uwCadenceFreqPu == 0) { alm_stDecCt.uwCadenceFlt ++; if(alm_stDecCt.uwCadenceFlt >= coef->uwCadenceFltCt) { alm_stDecCt.uwCadenceFlt = coef->uwCadenceFltCt; alm_unBikeCode.bit.CadenceSen = 1; alm_unAction.bit.PWMOff = 1; } } else if(in->blCadenceFreqOvrFlg) { alm_unBikeCode.bit.CadenceSen = 1; alm_unAction.bit.PWMOff = 1; } else { alm_stDecCt.uwCadenceFlt = 0; } } else { alm_stDecCt.uwCadenceFlt = 0; } } else { alm_stDecCt.uwCadenceFlt = 0; } /* Bike torque sensor fault */ if((in->uwTroqReg < coef->uwTorqMinReg) || (in->uwTroqReg >= coef->uwTorqMaxReg)) //Fault: U_Torq < 0.1V or >=3V { alm_stDecCt.uwTorqFlt ++; if(alm_stDecCt.uwTorqFlt >= coef->uwTorqFltCt) { alm_stDecCt.uwTorqFlt = coef->uwTorqFltCt; alm_unBikeCode.bit.TorqSen = 1; alm_unAction.bit.PWMOff = 1; } } else { alm_stDecCt.uwTorqFlt = 0; } /* Bike throttle fault */ if(in->blThrottleExistFlg) { if((in->uwThrottleReg < coef->uwThrottleMinReg) || (in->uwThrottleReg >= coef->uwThrottleMaxReg)) // Fault: U_Throttle < 0.1V or >=3V { alm_stDecCt.uwThrottleFlt ++; if(alm_stDecCt.uwThrottleFlt >= coef->uwThrottleFltCt) { alm_stDecCt.uwThrottleFlt = coef->uwThrottleFltCt; alm_unBikeCode.bit.Throttle = 1; alm_unAction.bit.PWMOff = 1; } } else { alm_stDecCt.uwThrottleFlt = 0; } } /* PCB NTC fault */ if((in->uwPCBNTCReg < coef->uwNTCMinReg) || (in->uwPCBNTCReg > coef->uwNTCMaxReg)) // Fault: NTC>100k or <0.032k { alm_stDecCt.uwPCBNTCFlt ++; if(alm_stDecCt.uwPCBNTCFlt >= coef->uwPCBNTCFltCt) { alm_stDecCt.uwPCBNTCFlt = coef->uwPCBNTCFltCt; alm_unBikeCode.bit.PCBNTC = 1; alm_unAction.bit.PWMOff = 1; } } else { alm_stDecCt.uwPCBNTCFlt = 0; } /* Motor NTC fault */ if(in->blMotorNTCExistFlg) { if((in->uwMotorNTCReg < coef->uwNTCMinReg) || (in->uwMotorNTCReg > coef->uwNTCMaxReg)) // Fault: NTC>100k or <0.032k { alm_stDecCt.uwMotorNTCFlt ++; if(alm_stDecCt.uwMotorNTCFlt >= coef->uwMotorNTCFltCt) { alm_stDecCt.uwMotorNTCFlt = coef->uwMotorNTCFltCt; alm_unBikeCode.bit.MotorNTC = 1; alm_unAction.bit.PWMOff = 1; } } else { alm_stDecCt.uwMotorNTCFlt = 0; } } } /*************************************************************** Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: ****************************************************************/ void alm_voHandle1MS(const ALM_BIKE_IN *in) { if(alm_unBikeCode.all != 0) { /* Alarm handle FSM */ switch (alm_enBikeFSMStatus) { case Alm_Stop: if (alm_unAction.bit.PWMOff != 0) { alm_stStopCt.ulBikePWMOffCnt++; sysctrl_voPwmOff(); if (alm_stStopCt.ulBikePWMOffCnt > 200) // 200ms, SysFault_hook, Event 1ms { cmfsm_stFlg.blMotorStopFlg = TRUE; alm_stStopCt.ulBikePWMOffCnt = 0; } } if (cmfsm_stFlg.blMotorStopFlg) { sysfsm_stFlg.blFSMRstOvrFlg = FALSE; // Enable control mode FSM reset sysfsm_stFlg.blCtrlMdVarClcOvrFlg = FALSE; // Enable control mode variable clear alm_enBikeFSMStatus = Alm_VarClc; } break; case Alm_VarClc: if (sysfsm_stFlg.blFSMRstOvrFlg && sysfsm_stFlg.blCtrlMdVarClcOvrFlg) { alm_enBikeFSMStatus = Alm_Reset; } break; case Alm_Reset: alm_voReset1MS(in, &alm_stReset1MSCoef, &alm_stDetect200MSCoef); break; default: break; } } } /*************************************************************** Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: ****************************************************************/ void alm_voReset1MSCoef(const ALM_RESET1MS_COFIN *in, ALM_RESET1MS_COF *out) { out->ulRecAllValCt = (ULONG)in->uwBikeGlblTm * in->uwFT1MSHz / 1000; out->ulRecBikeSpdCt = (ULONG)in->uwBikeSpdFltTm * in->uwFT1MSHz / 1000; out->ulRecCadenceCt = (ULONG)in->uwCadenceFltTm * in->uwFT1MSHz / 1000; out->ulRecTorqCt = (ULONG)in->uwTorqFltTm * in->uwFT1MSHz / 1000; out->ulRecThrottleCt = (ULONG)in->uwThrottleFltTm * in->uwFT1MSHz / 1000; out->ulRecPCBNTCCt = (ULONG)in->uwPCBNTCFltTm * in->uwFT1MSHz / 1000; out->ulRecMotorNTCCt = (ULONG)in->uwMotorNTCFltTm * in->uwFT1MSHz / 1000; } /*************************************************************** Function: Description: Call by: Input Variables: Output/Return Variables: Subroutine Call: Reference: ****************************************************************/ void alm_voReset1MS(const ALM_BIKE_IN *in, const ALM_RESET1MS_COF *coef, const ALM_DETEC200MS_COF *detctcoef) /* parasoft-suppress METRICS-28 "本项目圈复杂度无法更改,后续避免" */ { /*======================================================================= Recover condition =======================================================================*/ /* Recover time of global */ if (alm_stRecCt.ulBikeGlbl < coef->ulRecAllValCt) // 1s { alm_stRecCt.ulBikeGlbl++; } /* Recover time of bike speed sensor fault */ if((!in->blBikeSpdOvrFlg) && (in->uwBikeSpdPu > 0)) { if(alm_stRecCt.ulBikeSpdFlt < coef->ulRecBikeSpdCt) { alm_stRecCt.ulBikeSpdFlt++; } } /* Recover time of bike candence sensor fault */ if((!in->blCadenceFreqOvrFlg) && (in->uwCadenceFreqPu > 0)) { if (alm_stRecCt.ulCadenceFlt < coef->ulRecCadenceCt) { alm_stRecCt.ulCadenceFlt++; } } /* Recover time of bike torque sensor fault */ if((in->uwTroqReg > detctcoef->uwTorqMinReg) && (in->uwTroqReg < detctcoef->uwTorqMaxReg)) { if (alm_stRecCt.ulTorqFlt < coef->ulRecTorqCt) { alm_stRecCt.ulTorqFlt++; } } else { alm_stRecCt.ulTorqFlt = 0; } /* Recover time of bike throttle fault */ if((in->uwThrottleReg > detctcoef->uwThrottleMinReg) && (in->uwThrottleReg < detctcoef->uwThrottleMaxReg)) { if (alm_stRecCt.ulThrottleFlt < coef->ulRecThrottleCt) { alm_stRecCt.ulThrottleFlt++; } } else { alm_stRecCt.ulThrottleFlt = 0; } /* Recover time of PCB NTC fault */ if((in->uwPCBNTCReg > detctcoef->uwNTCMinReg) && (in->uwThrottleReg < detctcoef->uwNTCMaxReg)) { if (alm_stRecCt.ulPCBNTCFlt < coef->ulRecPCBNTCCt) { alm_stRecCt.ulPCBNTCFlt++; } } else { alm_stRecCt.ulPCBNTCFlt = 0; } /* Recover time of motor NTC fault */ if((in->uwPCBNTCReg > detctcoef->uwNTCMinReg) && (in->uwThrottleReg < detctcoef->uwNTCMaxReg)) { if (alm_stRecCt.ulMotorNTCFlt < coef->ulRecMotorNTCCt) { alm_stRecCt.ulMotorNTCFlt++; } } else { alm_stRecCt.ulMotorNTCFlt = 0; } /*======================================================================= Alarm code clear =======================================================================*/ if (alm_stRecCt.ulBikeGlbl >= coef->ulRecAllValCt) { /* Bike speed sensor fault */ if((alm_unBikeCode.bit.BikeSpdSen != 0) && (alm_stRecCt.ulBikeSpdFlt >= coef->ulRecBikeSpdCt)) { alm_stDecCt.uwBikeSpdFlt = 0; alm_unBikeCode.bit.BikeSpdSen = 0; } /* Bike cadence sensor fault */ if((alm_unBikeCode.bit.CadenceSen != 0) && (alm_stRecCt.ulCadenceFlt >= coef->ulRecCadenceCt)) { alm_stDecCt.uwCadenceFlt = 0; alm_unBikeCode.bit.CadenceSen = 0; } /* Bike torque sensor fault */ if((alm_unBikeCode.bit.TorqSen != 0) && (alm_stRecCt.ulTorqFlt >= coef->ulRecTorqCt)) { alm_stDecCt.uwTorqFlt = 0; alm_unBikeCode.bit.TorqSen = 0; } /* Bike throttle fault */ if((alm_unBikeCode.bit.Throttle != 0) && (alm_stRecCt.ulThrottleFlt >= coef->ulRecThrottleCt)) { alm_stDecCt.uwThrottleFlt = 0; alm_unBikeCode.bit.Throttle = 0; } /* PCB NTC fault */ if((alm_unBikeCode.bit.PCBNTC != 0) && (alm_stRecCt.ulPCBNTCFlt >= coef->ulRecPCBNTCCt)) { alm_stDecCt.uwPCBNTCFlt = 0; alm_unBikeCode.bit.PCBNTC = 0; } /* Motor NTC fault */ if((alm_unBikeCode.bit.MotorNTC != 0) && (alm_stRecCt.ulMotorNTCFlt >= coef->ulRecMotorNTCCt)) { alm_stDecCt.uwMotorNTCFlt = 0; alm_unBikeCode.bit.MotorNTC = 0; } } /*======================================================================= Alarm flag clear =======================================================================*/ if(alm_unBikeCode.all == 0) { /* Clear stop count */ alm_stStopCt.ulBikePWMOffCnt = 0; /* Clear recover count */ alm_stRecCt.ulBikeGlbl = 0; alm_stRecCt.ulBikeSpdFlt = 0; alm_stRecCt.ulCadenceFlt = 0; alm_stRecCt.ulTorqFlt = 0; alm_stRecCt.ulThrottleFlt = 0; alm_stRecCt.ulPCBNTCFlt = 0; alm_stRecCt.ulMotorNTCFlt = 0; } } /************************************************************************* Local Functions (N/A) *************************************************************************/ /************************************************************************ Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd. All rights reserved. *************************************************************************/ #ifdef _ALARM_C_ #undef _ALARM_C_ #endif /************************************************************************* End of this File (EOF): !!!!!!Do not put anything after this part!!!!!!!!!!! *************************************************************************/