/************************************************************************ Project: Welling Motor Control Paltform Filename: pwm.c Partner Filename: pwm.h Description: SVPWM and over voltage modulation Complier: IAR Embedded Workbench for ARM 7.80.4 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 _PWM_C_ #define _PWM_C_ #endif /************************************************************************ Include File ************************************************************************/ #include "syspar.h" #include "user.h" /************************************************************************ Private Variables *************************************************************************/ static SWORD pwm_pvt_sw1st_Cur_Smpl_Ct = 0; static SWORD pwm_pvt_sw2nd_Cur_Smpl_Ct = 0; static SWORD pwm_pvt_swMin_Double_Cur_Smpl_Pu = 0; static SWORD pwm_pvt_swMin_Cur_Smpl_Ct = 0; static SWORD pwm_pvt_swMin_Cur_Smpl_Pu = 0; /************************************************************************ Constant Table: ************************************************************************/ /************************************************************************ Exported Functions: ************************************************************************/ /************************************************************************ Function: pwm_voInit; Description: pwm generation initial; Call by: functions in main loop; Input Variables: N/A; Output/Return Variables: N/A; Subroutine Call: N/A; Reference: N/A; ************************************************************************/ void pwm_voInit(void) { pwm_sw1stCurSmplCt = cp_stControlPara.swPWM1STSampleCnt; // min time for ADC one channel of Current pwm_sw2ndCurSmplCt = cp_stControlPara.swPWM2NDSampleCnt; // the time of second current sample trig lag the second comparator pwm_swMinDoubleCurSmplPu = (cp_stControlPara.swPWMMinEffVectorPu << 1); // min time of Two valid voltage vector pwm_swMinCurSmplCt = cp_stControlPara.swPWMMinEffVectorCnt; // min counts of one valid voltage vector pwm_swMinCurSmplPu = cp_stControlPara.swPWMMinEffVectorCnt; // min time of one valid voltage vector pwm_pvt_sw1st_Cur_Smpl_Ct = pwm_sw1stCurSmplCt; pwm_pvt_sw2nd_Cur_Smpl_Ct = pwm_sw2ndCurSmplCt; pwm_pvt_swMin_Double_Cur_Smpl_Pu = pwm_swMinDoubleCurSmplPu; pwm_pvt_swMin_Cur_Smpl_Ct = pwm_swMinCurSmplCt; pwm_pvt_swMin_Cur_Smpl_Pu = pwm_swMinCurSmplPu; pwm_stGenOut.swUalphaPu = 0; // Q14 pwm_stGenOut.swUbetaPu = 0; // Q14 pwm_stGenOut.uwNewSectorNum = 0; pwm_stGenOut.uwNewTIM1COMPR[0] = HW_INIT_HHPWM_PERIOD; pwm_stGenOut.uwNewTIM1COMPR[1] = HW_INIT_HHPWM_PERIOD; pwm_stGenOut.uwNewTIM1COMPR[2] = HW_INIT_HHPWM_PERIOD; pwm_stGenOut.uwNewTIM1COMPR[3] = HW_INIT_HHPWM_PERIOD; pwm_stGenOut.uwNewTIM1COMPR[4] = HW_INIT_HHPWM_PERIOD; pwm_stGenOut.uwNewTIM1COMPR[5] = HW_INIT_HHPWM_PERIOD; pwm_stGenOut.uwFirstTrigCOMPR = HW_INIT_HHHPWM_PERIOD; pwm_stGenOut.uwSecondTrigCOMPR = HW_INIT_HHPWM_PERIOD + HW_INIT_HHHPWM_PERIOD; pwm_stGenOut.uwOldTrig = 0; pwm_stGenOut.uwNewTrig = 0; pwm_stGenOut.uwSampleArea = IgnoreNone; pwm_stGenOut.uwRdsonTrig = 129; pwm_stGenOut.uwSigRTrig = HW_INIT_HHHPWM_PERIOD; pwm_stGenOut.blSampleCalibFlag = FALSE; } /************************************************************************ Function: pwm_voGenCoef; Description: pwm generation coefficient initial; Call by: functions in main loop; Input Variables: PWM_COF_IN; Output/Return Variables: PWM_CALC_COF; Subroutine Call: N/A; Reference: N/A; ************************************************************************/ void pwm_voGenCoef(PWM_COF_IN *in, PWM_CALC_COF *coef) { if (in->uwPWMDutyMax > 1000) { in->uwPWMDutyMax = 1000; } else if (in->uwPWMDutyMax == 0) { in->uwPWMDutyMax = 1; } else { //do nothing } if (in->uwPWM7To5Duty > 1000) { in->uwPWM7To5Duty = 1000; } else if (in->uwPWM7To5Duty == 0) { in->uwPWM7To5Duty = 1; } else { //do nothing } if (in->uwOvmNo > 2) { in->uwOvmNo = 2; } if (in->uwPWMPd > 31250) { in->uwPWMPd = 31250; } else if (in->uwPWMPd < 4) { in->uwPWMPd = 4; } else { //do nothing } coef->uwPWMDutyMaxPu = (UWORD)((((ULONG)in->uwPWMDutyMax - 3) << 14) / 1000); // Q14 coef->uwPWM7To5DutyPu = (UWORD)(((ULONG)in->uwPWM7To5Duty << 14) / 1000); // Q14 coef->uwPWMMinSample1Pu = (UWORD)(((ULONG)in->uwPWMMinSample1Pu << 14) / 1000); // Q14, unit:Pu two zero vector coef->uwPWMMinSample2Pu = (UWORD)(((ULONG)in->uwPWMMinSample2Pu << 14) / 1000); // Q14, unit:Pu (one zero vector + sample time)*2 coef->uwPWMMinSample3Pu = (UWORD)(((ULONG)in->uwPWMMinSample3Pu << 14) / 1000); // Q14, unit:Pu (one Singel Resistance steady time + sample time)*2 coef->uwOvmNo = in->uwOvmNo; coef->uwPWMPd = in->uwPWMPd; coef->uwHPWMPd = in->uwPWMPd >> 1; coef->uwHHPWMPd = in->uwPWMPd >> 2; coef->ulPWMPerInv = ((ULONG)1 << 21) / in->uwPWMPd; // Q21, 1/PWM period coef->uwMaxCmpCt = (UWORD)(((ULONG)in->uwPWMDutyMax * coef->uwHPWMPd) / 1000); // Q14 coef->uwSampleSteadyCt = (UWORD)(((ULONG)in->uwSampleSteadyPu * coef->uwHPWMPd) / 1000); coef->uwSingelResisSampleCt = (UWORD)(((ULONG)in->uwSingelResisSamplePu * coef->uwHPWMPd) / 1000); } /************************************************************************ Function: pwm_voGen; Description: pwm generation; Call by: functions in TBC; Input Variables: PWM_GEN_IN, PWM_CALC_COF; Output/Return Variables: PWM_GEN_OUT; Subroutine Call: N/A; Reference: N/A; ************************************************************************/ void pwm_voGen(PWM_GEN_IN *in, const PWM_CALC_COF *coef, PWM_GEN_OUT *out) { SLONG slL1, slL2, slL3; SLONG slKsvpwm; SLONG slX, slY, slZ; SWORD swT1, swT2; SWORD swOvmT1, swOvmT2; UWORD uwSector; SWORD swUaPu, swUbPu, swUcPu; SWORD swPWMPRD1, swPWMPRD2, swPWMPRD3; // SWORD swPWMPRD11,swPWMPRD21,swPWMPRD31,swPWMPRD12,swPWMPRD22,swPWMPRD32; SWORD tmp_swPeriodA, tmp_swPeriodB, tmp_swPeriodC; /*============================================================================== Sector Determination L1 = Ubeta L2 = sqrt(3)/2 * Ualfa - 1/2 * Ubeta L3 = -sqrt(3)/2 * Ualfa - 1/2 * Ubeta ==============================================================================*/ slL1 = in->swUbetaPu + 1; // Q14 slL2 = ((in->swUalphaPu * PWM_SQRT3 >> 14) - in->swUbetaPu) >> 1; // Q14 slL3 = (-(in->swUalphaPu * PWM_SQRT3 >> 14) - in->swUbetaPu) >> 1; // Q14 uwSector = 0; if (slL1 > 0) { uwSector += 1; } if (slL2 > 0) { uwSector += 2; } if (slL3 > 0) { uwSector += 4; } /*====================================================================== Base Voltage Vector Period(t1/t2) calculation according to sector X = 2/sqrt(3)*Ts*slv1 Y = -2/sqrt(3)*Ts*slv3 Z = -2/sqrt(3)*Ts*slv2 =======================================================================*/ if (in->uwVdcPu < 10) { in->uwVdcPu = 10; } slKsvpwm = (PWM_SQRT3 << 15) / in->uwVdcPu; // Q15=Q14+Q15-Q14 slX = slKsvpwm * (slL1 - 1) >> 15; // Q14 slY = -slKsvpwm * slL3 >> 15; // Q14 slZ = -slKsvpwm * slL2 >> 15; // Q14 switch (uwSector) { case 3: swT1 = -(SWORD)slZ; // Q14, t1 swT2 = (SWORD)slX; // Q14, t2 break; case 1: swT1 = (SWORD)slZ; // Q14, t1 swT2 = (SWORD)slY; // Q14, t2 break; case 5: swT1 = (SWORD)slX; // Q14, t1 swT2 = -(SWORD)slY; // Q14, t2 break; case 4: swT1 = -(SWORD)slX; // Q14, t1 swT2 = (SWORD)slZ; // Q14, t2 break; case 6: swT1 = -(SWORD)slY; // Q14, t1 swT2 = -(SWORD)slZ; // Q14, t2 break; case 2: swT1 = (SWORD)slY; // Q14, t1 swT2 = -(SWORD)slX; // Q14, t2 break; default: swT1 = 0; swT2 = 0; break; } /*================================================================ Over voltage modulation ================================================================*/ switch (coef->uwOvmNo) { case 0: /* SVPWM over modulation: min phase error */ if ((swT1 + swT2) > coef->uwPWMDutyMaxPu) { swOvmT1 = (SWORD)(swT1 * (SLONG)coef->uwPWMDutyMaxPu / (swT1 + swT2)); // Q14=Q14+Q14-Q14 swOvmT2 = (SWORD)coef->uwPWMDutyMaxPu - swOvmT1; out->blOvmFlag = TRUE; } else { swOvmT1 = swT1; swOvmT2 = swT2; out->blOvmFlag = FALSE; } break; case 1: /* SVPWM over modulation: min amplitude error */ if ((swT1 + swT2) > coef->uwPWMDutyMaxPu) { swOvmT1 = swT1 - ((swT1 + swT2 - (SWORD)coef->uwPWMDutyMaxPu) >> 1); swOvmT2 = swT2 - ((swT1 + swT2 - (SWORD)coef->uwPWMDutyMaxPu) >> 1); if (swOvmT1 < 0) { swOvmT1 = 0; swOvmT2 = (SWORD)coef->uwPWMDutyMaxPu; } if (swOvmT2 < 0) { swOvmT2 = 0; swOvmT1 = (SWORD)coef->uwPWMDutyMaxPu; } out->blOvmFlag = TRUE; } else { swOvmT1 = swT1; swOvmT2 = swT2; out->blOvmFlag = FALSE; } break; case 2: /* SVPWM over modulation: amplitude and phase optimum */ if ((swT1 + swT2) > coef->uwPWMDutyMaxPu) { if (swT1 > swT2) { if (swT1 > coef->uwPWMDutyMaxPu) { swOvmT1 = (SWORD)coef->uwPWMDutyMaxPu; } else { swOvmT1 = swT1; } swOvmT2 = (SWORD)coef->uwPWMDutyMaxPu - swOvmT1; } else { if (swT2 > (SWORD)coef->uwPWMDutyMaxPu) { swOvmT2 = (SWORD)coef->uwPWMDutyMaxPu; } else { swOvmT2 = swT2; } swOvmT1 = (SWORD)coef->uwPWMDutyMaxPu - swOvmT2; } out->blOvmFlag = TRUE; } else { swOvmT1 = swT1; swOvmT2 = swT2; out->blOvmFlag = FALSE; } break; default: /* SVPWM over modulation: amplitude and phase optimum */ if ((swT1 + swT2) > coef->uwPWMDutyMaxPu) { if (swT1 > swT2) { if (swT1 > coef->uwPWMDutyMaxPu) { swOvmT1 = (SWORD)coef->uwPWMDutyMaxPu; } else { swOvmT1 = swT1; } swOvmT2 = (SWORD)coef->uwPWMDutyMaxPu - swOvmT1; } else { if (swT2 > coef->uwPWMDutyMaxPu) { swOvmT2 = (SWORD)coef->uwPWMDutyMaxPu; } else { swOvmT2 = swT2; } swOvmT1 = (SWORD)coef->uwPWMDutyMaxPu - swOvmT2; } out->blOvmFlag = TRUE; } else { swOvmT1 = swT1; swOvmT2 = swT2; out->blOvmFlag = FALSE; } break; } if(cp_stFlg.CurrentSampleModelSelect == COMBINATION) { /*================================================================ Calculate compare value ================================================================*/ if ((swOvmT1 + swOvmT2) > (SWORD)coef->uwPWM7To5DutyPu) /* Five SVPWM */ { swPWMPRD1 = (SWORD)coef->uwHPWMPd; swPWMPRD2 = (SWORD)(((SLONG)16384 - swOvmT2) * (SWORD)coef->uwHPWMPd >> 14); swPWMPRD3 = (SWORD)(((SLONG)16384 - swOvmT1 - swOvmT2) * (SWORD)coef->uwHPWMPd >> 14); } else /* Seven SVPWM */ { swPWMPRD1 = (SWORD)(((SLONG)16384 + swOvmT1 + swOvmT2) * (SWORD)coef->uwHHPWMPd >> 14); swPWMPRD2 = (SWORD)(((SLONG)16384 + swOvmT1 - swOvmT2) * (SWORD)coef->uwHHPWMPd >> 14); swPWMPRD3 = (SWORD)(((SLONG)16384 - swOvmT1 - swOvmT2) * (SWORD)coef->uwHHPWMPd >> 14); } if (swOvmT2 > coef->uwPWMMinSample3Pu) { out->blSampleCalibFlag = TRUE; //out->uwSigRTrig = swPWMPRD2 + coef->uwSingelResisSampleCt; out->uwSigRTrig = swPWMPRD1 - coef->uwSingelResisSampleCt; } else { out->blSampleCalibFlag = FALSE; out->uwSigRTrig = HW_INIT_HHHPWM_PERIOD;//coef->uwHPWMPd; } out->uwSingelRSampleAreaLast = out->uwSingelRSampleArea; if(1)//sysctrl_stPwmState.blChargeOvrFlg == TRUE) { switch (uwSector) { case 3: out->uwNewTIM1COMPR[0] = swPWMPRD3; out->uwNewTIM1COMPR[1] = swPWMPRD2; out->uwNewTIM1COMPR[2] = swPWMPRD1; out->uwNewTIM1COMPR[3] = swPWMPRD3; out->uwNewTIM1COMPR[4] = swPWMPRD2; out->uwNewTIM1COMPR[5] = swPWMPRD1; if (out->blSampleCalibFlag == TRUE) { out->uwSingelRSampleArea = SampleC; } else { out->uwSingelRSampleArea = SampleNone; } break; case 1: out->uwNewTIM1COMPR[0] = swPWMPRD2; out->uwNewTIM1COMPR[1] = swPWMPRD3; out->uwNewTIM1COMPR[2] = swPWMPRD1; out->uwNewTIM1COMPR[3] = swPWMPRD2; out->uwNewTIM1COMPR[4] = swPWMPRD3; out->uwNewTIM1COMPR[5] = swPWMPRD1; if (out->blSampleCalibFlag == TRUE) { out->uwSingelRSampleArea = SampleC; } else { out->uwSingelRSampleArea = SampleNone; } break; case 5: out->uwNewTIM1COMPR[0] = swPWMPRD1; out->uwNewTIM1COMPR[1] = swPWMPRD3; out->uwNewTIM1COMPR[2] = swPWMPRD2; out->uwNewTIM1COMPR[3] = swPWMPRD1; out->uwNewTIM1COMPR[4] = swPWMPRD3; out->uwNewTIM1COMPR[5] = swPWMPRD2; if (out->blSampleCalibFlag == TRUE) { out->uwSingelRSampleArea = SampleA; } else { out->uwSingelRSampleArea = SampleNone; } break; case 4: out->uwNewTIM1COMPR[0] = swPWMPRD1; out->uwNewTIM1COMPR[1] = swPWMPRD2; out->uwNewTIM1COMPR[2] = swPWMPRD3; out->uwNewTIM1COMPR[3] = swPWMPRD1; out->uwNewTIM1COMPR[4] = swPWMPRD2; out->uwNewTIM1COMPR[5] = swPWMPRD3; if (out->blSampleCalibFlag == TRUE) { out->uwSingelRSampleArea = SampleA; } else { out->uwSingelRSampleArea = SampleNone; } break; case 6: out->uwNewTIM1COMPR[0] = swPWMPRD2; out->uwNewTIM1COMPR[1] = swPWMPRD1; out->uwNewTIM1COMPR[2] = swPWMPRD3; out->uwNewTIM1COMPR[3] = swPWMPRD2; out->uwNewTIM1COMPR[4] = swPWMPRD1; out->uwNewTIM1COMPR[5] = swPWMPRD3; if (out->blSampleCalibFlag == TRUE) { out->uwSingelRSampleArea = SampleB; } else { out->uwSingelRSampleArea = SampleNone; } break; case 2: out->uwNewTIM1COMPR[0] = swPWMPRD3; out->uwNewTIM1COMPR[1] = swPWMPRD1; out->uwNewTIM1COMPR[2] = swPWMPRD2; out->uwNewTIM1COMPR[3] = swPWMPRD3; out->uwNewTIM1COMPR[4] = swPWMPRD1; out->uwNewTIM1COMPR[5] = swPWMPRD2; if (out->blSampleCalibFlag == TRUE) { out->uwSingelRSampleArea = SampleB; } else { out->uwSingelRSampleArea = SampleNone; } break; default: out->uwNewTIM1COMPR[0] = coef->uwHHPWMPd; out->uwNewTIM1COMPR[1] = coef->uwHHPWMPd; out->uwNewTIM1COMPR[2] = coef->uwHHPWMPd; out->uwNewTIM1COMPR[3] = coef->uwHHPWMPd; out->uwNewTIM1COMPR[4] = coef->uwHHPWMPd; out->uwNewTIM1COMPR[5] = coef->uwHHPWMPd; out->uwSingelRSampleArea = SampleNone; break; } } /* Calculate actual output voltage */ out->uwNewSectorNum = uwSector; out->uwPWMNewSectorNum = out->uwNewSectorNum; tmp_swPeriodA = (SWORD)coef->uwPWMPd - (SWORD)out->uwNewTIM1COMPR[0] - (SWORD)out->uwNewTIM1COMPR[3]; tmp_swPeriodB = (SWORD)coef->uwPWMPd - (SWORD)out->uwNewTIM1COMPR[1] - (SWORD)out->uwNewTIM1COMPR[4]; tmp_swPeriodC = (SWORD)coef->uwPWMPd - (SWORD)out->uwNewTIM1COMPR[2] - (SWORD)out->uwNewTIM1COMPR[5]; swUaPu = (SWORD)(((((SLONG)tmp_swPeriodA * (SLONG)coef->ulPWMPerInv) >> 5) * (SWORD)in->uwVdcPu) >> 16); // Q21-Q5+Q14-Q16=Q14 swUbPu = (SWORD)(((((SLONG)tmp_swPeriodB * (SLONG)coef->ulPWMPerInv) >> 5) * (SWORD)in->uwVdcPu) >> 16); // Q21-Q5+Q14-Q16=Q14 swUcPu = (SWORD)(((((SLONG)tmp_swPeriodC * (SLONG)coef->ulPWMPerInv) >> 5) * (SWORD)in->uwVdcPu) >> 16); // Q21-Q5+Q14-Q16=Q14 out->swUalphaPu = (swUaPu + swUaPu - swUbPu - swUcPu) * PWM_1DIV3 >> 14; // Q14=Q14+Q14-Q14 out->swUbetaPu = (swUbPu - swUcPu) * PWM_SQRT3_INV >> 14; // Q14=Q14+Q14-Q14 out->uwRdsonTrig = 129 ; } else if(cp_stFlg.CurrentSampleModelSelect == SINGLERESISITANCE) { SWORD swPWMPRD11=0; SWORD swPWMPRD21=0; SWORD swPWMPRD31=0; SWORD swPWMPRD12=0; SWORD swPWMPRD22=0; SWORD swPWMPRD32=0; /*1/4 of zero vector in the middle,and others apart in the beginning and ending*/ swPWMPRD1 = (SWORD)((((SLONG)16384 * 3 + swOvmT1 + swOvmT2) * (SWORD)coef->uwPWMPd) >> 17); // Q14 swPWMPRD2 = (SWORD)((((SLONG)16384 * 3 + swOvmT1 - swOvmT2 * 3) * (SWORD)coef->uwPWMPd) >> 17); swPWMPRD3 = (SWORD)((((SLONG)16384 - swOvmT1 - swOvmT2) * 3 * (SWORD)coef->uwPWMPd) >> 17); swPWMPRD11 = swPWMPRD1; swPWMPRD21 = swPWMPRD2; swPWMPRD31 = swPWMPRD3; swPWMPRD12 = swPWMPRD1; swPWMPRD22 = swPWMPRD2; swPWMPRD32 = swPWMPRD3; /* comparision value correction when two vectors are both too short*/ if ((swOvmT1 + swOvmT2) < (pwm_pvt_swMin_Double_Cur_Smpl_Pu << 1)) { if ((swOvmT1 - pwm_pvt_swMin_Double_Cur_Smpl_Pu) < 0) { swPWMPRD31 = swPWMPRD2 - pwm_pvt_swMin_Cur_Smpl_Ct; swPWMPRD32 = (swPWMPRD3 << 1) - swPWMPRD31; } if ((swOvmT2 - pwm_pvt_swMin_Double_Cur_Smpl_Pu) < 0) { swPWMPRD11 = swPWMPRD2 + pwm_pvt_swMin_Cur_Smpl_Ct; swPWMPRD12 = (swPWMPRD1 << 1) - swPWMPRD11; } } else { if ((swOvmT2 - pwm_pvt_swMin_Double_Cur_Smpl_Pu) < 0) { if (((coef->uwHPWMPd + swPWMPRD1 - 2 * swPWMPRD2) <= pwm_pvt_swMin_Cur_Smpl_Ct) && ((swOvmT1 + swOvmT2) > coef->uwPWM7To5DutyPu)) { swPWMPRD1 = (SWORD)((((SLONG)swOvmT1 + swOvmT2) * (SLONG)coef->uwPWMPd) >> 15); swPWMPRD2 = (SWORD)(((SLONG)swOvmT1 * (SLONG)coef->uwPWMPd) >> 15); swPWMPRD3 = 0; swPWMPRD11 = (SWORD)coef->uwHPWMPd; swPWMPRD12 = (swPWMPRD1 << 1) - swPWMPRD11; swPWMPRD31 = swPWMPRD3; swPWMPRD32 = swPWMPRD3; swPWMPRD22 = (SWORD)coef->uwHPWMPd; swPWMPRD21 = (swPWMPRD2 << 1) - swPWMPRD22; } else { swPWMPRD21 = swPWMPRD1 - pwm_pvt_swMin_Cur_Smpl_Ct; swPWMPRD22 = (swPWMPRD2 << 1) - swPWMPRD21; } } else if ((swOvmT1 - pwm_pvt_swMin_Double_Cur_Smpl_Pu) < 0) { if (((2 * swPWMPRD2 - swPWMPRD3) <= pwm_pvt_swMin_Cur_Smpl_Ct) && ((swOvmT1 + swOvmT2) > coef->uwPWM7To5DutyPu)) { swPWMPRD1 = (SWORD)coef->uwHPWMPd; swPWMPRD2 = (SWORD)(((SLONG)16384 - swOvmT2) * (SWORD)coef->uwPWMPd >> 15); swPWMPRD3 = (SWORD)(((SLONG)16384 - swOvmT1 - swOvmT2) * (SWORD)coef->uwPWMPd >> 15); swPWMPRD11 = swPWMPRD1; swPWMPRD12 = swPWMPRD1; swPWMPRD22 = 0; swPWMPRD21 = (swPWMPRD2 << 1) - swPWMPRD22; swPWMPRD31 = 0; swPWMPRD32 = (swPWMPRD3 << 1) - swPWMPRD31; } else { swPWMPRD21 = swPWMPRD3 + pwm_pvt_swMin_Cur_Smpl_Ct; swPWMPRD22 = (swPWMPRD2 << 1) - swPWMPRD21; } } else { //do nothing } } out->uwOldTrig = out->uwNewTrig; out->uwNewTrig = swPWMPRD21; switch (uwSector) { case 3: out->uwNewTIM1COMPR[0] = swPWMPRD31; out->uwNewTIM1COMPR[1] = swPWMPRD21; out->uwNewTIM1COMPR[2] = swPWMPRD11; out->uwNewTIM1COMPR[3] = swPWMPRD32; out->uwNewTIM1COMPR[4] = swPWMPRD22; out->uwNewTIM1COMPR[5] = swPWMPRD12; out->uwFirstTrigCOMPR = swPWMPRD21 - pwm_pvt_sw1st_Cur_Smpl_Ct; out->uwSecondTrigCOMPR = swPWMPRD21 + pwm_pvt_sw2nd_Cur_Smpl_Ct; break; case 1: out->uwNewTIM1COMPR[0] = swPWMPRD21; out->uwNewTIM1COMPR[1] = swPWMPRD31; out->uwNewTIM1COMPR[2] = swPWMPRD11; out->uwNewTIM1COMPR[3] = swPWMPRD22; out->uwNewTIM1COMPR[4] = swPWMPRD32; out->uwNewTIM1COMPR[5] = swPWMPRD12; out->uwFirstTrigCOMPR = swPWMPRD21 - pwm_pvt_sw1st_Cur_Smpl_Ct; out->uwSecondTrigCOMPR = swPWMPRD21 + pwm_pvt_sw2nd_Cur_Smpl_Ct; break; case 5: out->uwNewTIM1COMPR[0] = swPWMPRD11; out->uwNewTIM1COMPR[1] = swPWMPRD31; out->uwNewTIM1COMPR[2] = swPWMPRD21; out->uwNewTIM1COMPR[3] = swPWMPRD12; out->uwNewTIM1COMPR[4] = swPWMPRD32; out->uwNewTIM1COMPR[5] = swPWMPRD22; out->uwFirstTrigCOMPR = swPWMPRD21 - pwm_pvt_sw1st_Cur_Smpl_Ct; out->uwSecondTrigCOMPR = swPWMPRD21 + pwm_pvt_sw2nd_Cur_Smpl_Ct; break; case 4: out->uwNewTIM1COMPR[0] = swPWMPRD11; out->uwNewTIM1COMPR[1] = swPWMPRD21; out->uwNewTIM1COMPR[2] = swPWMPRD31; out->uwNewTIM1COMPR[3] = swPWMPRD12; out->uwNewTIM1COMPR[4] = swPWMPRD22; out->uwNewTIM1COMPR[5] = swPWMPRD32; out->uwFirstTrigCOMPR = swPWMPRD21 - pwm_pvt_sw1st_Cur_Smpl_Ct; out->uwSecondTrigCOMPR = swPWMPRD21 + pwm_pvt_sw2nd_Cur_Smpl_Ct; break; case 6: out->uwNewTIM1COMPR[0] = swPWMPRD21; out->uwNewTIM1COMPR[1] = swPWMPRD11; out->uwNewTIM1COMPR[2] = swPWMPRD31; out->uwNewTIM1COMPR[3] = swPWMPRD22; out->uwNewTIM1COMPR[4] = swPWMPRD12; out->uwNewTIM1COMPR[5] = swPWMPRD32; out->uwFirstTrigCOMPR = swPWMPRD21 - pwm_pvt_sw1st_Cur_Smpl_Ct; out->uwSecondTrigCOMPR = swPWMPRD21 + pwm_pvt_sw2nd_Cur_Smpl_Ct; break; case 2: out->uwNewTIM1COMPR[0] = swPWMPRD31; out->uwNewTIM1COMPR[1] = swPWMPRD11; out->uwNewTIM1COMPR[2] = swPWMPRD21; out->uwNewTIM1COMPR[3] = swPWMPRD32; out->uwNewTIM1COMPR[4] = swPWMPRD12; out->uwNewTIM1COMPR[5] = swPWMPRD22; out->uwFirstTrigCOMPR = swPWMPRD21 - pwm_pvt_sw1st_Cur_Smpl_Ct; out->uwSecondTrigCOMPR = swPWMPRD21 + pwm_pvt_sw2nd_Cur_Smpl_Ct; break; default: out->uwNewTIM1COMPR[0] = coef->uwHHPWMPd; out->uwNewTIM1COMPR[1] = coef->uwHHPWMPd; out->uwNewTIM1COMPR[2] = coef->uwHHPWMPd; out->uwNewTIM1COMPR[3] = coef->uwHHPWMPd; out->uwNewTIM1COMPR[4] = coef->uwHHPWMPd; out->uwNewTIM1COMPR[5] = coef->uwHHPWMPd; out->uwFirstTrigCOMPR = coef->uwHHPWMPd >> 1; out->uwSecondTrigCOMPR = coef->uwHPWMPd - coef->uwHHPWMPd >> 1; break; } out->uwNewSectorNum = uwSector; out->uwPWMNewSectorNum = out->uwNewSectorNum; tmp_swPeriodA = (SWORD)coef->uwPWMPd - (SWORD)out->uwNewTIM1COMPR[0] - (SWORD)out->uwNewTIM1COMPR[3]; tmp_swPeriodB = (SWORD)coef->uwPWMPd - (SWORD)out->uwNewTIM1COMPR[1] - (SWORD)out->uwNewTIM1COMPR[4]; tmp_swPeriodC = (SWORD)coef->uwPWMPd - (SWORD)out->uwNewTIM1COMPR[2] - (SWORD)out->uwNewTIM1COMPR[5]; swUaPu = (SWORD)(((tmp_swPeriodA * (SLONG)coef->ulPWMPerInv >> 5) * (SWORD)in->uwVdcPu) >> 16); // Q21-Q5+Q14-Q16=Q14 swUbPu = (SWORD)(((tmp_swPeriodB * (SLONG)coef->ulPWMPerInv >> 5) * (SWORD)in->uwVdcPu) >> 16); // Q21-Q5+Q14-Q16=Q14 swUcPu = (SWORD)(((tmp_swPeriodC * (SLONG)coef->ulPWMPerInv >> 5) * (SWORD)in->uwVdcPu) >> 16); // Q21-Q5+Q14-Q16=Q14 out->swUalphaPu = (swUaPu + swUaPu - swUbPu - swUcPu) * PWM_1DIV3 >> 14; // Q14=Q14+Q14-Q14 out->swUbetaPu = (swUbPu - swUcPu) * PWM_SQRT3_INV >> 14; // Q14=Q14+Q14-Q14 } else if(cp_stFlg.CurrentSampleModelSelect == RDSON) { /*================================================================ Calculate compare value ================================================================*/ if ((swOvmT1 + swOvmT2) > coef->uwPWM7To5DutyPu) /* Five SVPWM */ { swPWMPRD1 = (SWORD)coef->uwHPWMPd; swPWMPRD2 = (SWORD)((((SLONG)16384 - swOvmT2) * (SWORD)coef->uwHPWMPd) >> 14); swPWMPRD3 = (SWORD)((((SLONG)16384 - swOvmT1 - swOvmT2) * (SWORD)coef->uwHPWMPd) >> 14); } else /* Seven SVPWM */ { swPWMPRD1 = (SWORD)((((SLONG)16384 + swOvmT1 + swOvmT2) * (SWORD)coef->uwHHPWMPd) >> 14); swPWMPRD2 = (SWORD)((((SLONG)16384 + swOvmT1 - swOvmT2) * (SWORD)coef->uwHHPWMPd) >> 14); swPWMPRD3 = (SWORD)((((SLONG)16384 - swOvmT1 - swOvmT2) * (SWORD)coef->uwHHPWMPd) >> 14); } switch (uwSector) { case 3: out->uwNewTIM1COMPR[0] = swPWMPRD3; out->uwNewTIM1COMPR[1] = swPWMPRD2; out->uwNewTIM1COMPR[2] = swPWMPRD1; out->uwNewTIM1COMPR[3] = swPWMPRD3; out->uwNewTIM1COMPR[4] = swPWMPRD2; out->uwNewTIM1COMPR[5] = swPWMPRD1; break; case 1: out->uwNewTIM1COMPR[0] = swPWMPRD2; out->uwNewTIM1COMPR[1] = swPWMPRD3; out->uwNewTIM1COMPR[2] = swPWMPRD1; out->uwNewTIM1COMPR[3] = swPWMPRD2; out->uwNewTIM1COMPR[4] = swPWMPRD3; out->uwNewTIM1COMPR[5] = swPWMPRD1; break; case 5: out->uwNewTIM1COMPR[0] = swPWMPRD1; out->uwNewTIM1COMPR[1] = swPWMPRD3; out->uwNewTIM1COMPR[2] = swPWMPRD2; out->uwNewTIM1COMPR[3] = swPWMPRD1; out->uwNewTIM1COMPR[4] = swPWMPRD3; out->uwNewTIM1COMPR[5] = swPWMPRD2; break; case 4: out->uwNewTIM1COMPR[0] = swPWMPRD1; out->uwNewTIM1COMPR[1] = swPWMPRD2; out->uwNewTIM1COMPR[2] = swPWMPRD3; out->uwNewTIM1COMPR[3] = swPWMPRD1; out->uwNewTIM1COMPR[4] = swPWMPRD2; out->uwNewTIM1COMPR[5] = swPWMPRD3; break; case 6: out->uwNewTIM1COMPR[0] = swPWMPRD2; out->uwNewTIM1COMPR[1] = swPWMPRD1; out->uwNewTIM1COMPR[2] = swPWMPRD3; out->uwNewTIM1COMPR[3] = swPWMPRD2; out->uwNewTIM1COMPR[4] = swPWMPRD1; out->uwNewTIM1COMPR[5] = swPWMPRD3; break; case 2: out->uwNewTIM1COMPR[0] = swPWMPRD3; out->uwNewTIM1COMPR[1] = swPWMPRD1; out->uwNewTIM1COMPR[2] = swPWMPRD2; out->uwNewTIM1COMPR[3] = swPWMPRD3; out->uwNewTIM1COMPR[4] = swPWMPRD1; out->uwNewTIM1COMPR[5] = swPWMPRD2; break; default: out->uwNewTIM1COMPR[0] = coef->uwHHPWMPd; out->uwNewTIM1COMPR[1] = coef->uwHHPWMPd; out->uwNewTIM1COMPR[2] = coef->uwHHPWMPd; out->uwNewTIM1COMPR[3] = coef->uwHHPWMPd; out->uwNewTIM1COMPR[4] = coef->uwHHPWMPd; out->uwNewTIM1COMPR[5] = coef->uwHHPWMPd; break; } /* Calculate actual output voltage */ out->uwNewSectorNum = uwSector; out->uwPWMNewSectorNum = out->uwNewSectorNum; tmp_swPeriodA = (SWORD)coef->uwPWMPd - (SWORD)out->uwNewTIM1COMPR[0] - (SWORD)out->uwNewTIM1COMPR[3]; tmp_swPeriodB = (SWORD)coef->uwPWMPd - (SWORD)out->uwNewTIM1COMPR[1] - (SWORD)out->uwNewTIM1COMPR[4]; tmp_swPeriodC = (SWORD)coef->uwPWMPd - (SWORD)out->uwNewTIM1COMPR[2] - (SWORD)out->uwNewTIM1COMPR[5]; swUaPu = (SWORD)((((tmp_swPeriodA * (SLONG)coef->ulPWMPerInv) >> 5) * (SLONG)in->uwVdcPu) >> 16); // Q21-Q5+Q14-Q16=Q14 swUbPu = (SWORD)((((tmp_swPeriodB * (SLONG)coef->ulPWMPerInv) >> 5) * (SLONG)in->uwVdcPu) >> 16); // Q21-Q5+Q14-Q16=Q14 swUcPu = (SWORD)((((tmp_swPeriodC * (SLONG)coef->ulPWMPerInv) >> 5) * (SLONG)in->uwVdcPu) >> 16); // Q21-Q5+Q14-Q16=Q14 out->swUalphaPu = (swUaPu + swUaPu - swUbPu - swUcPu) * PWM_1DIV3 >> 14; // Q14=Q14+Q14-Q14 out->swUbetaPu = (swUbPu - swUcPu) * PWM_SQRT3_INV >> 14; // Q14=Q14+Q14-Q14 if ((16384 - swOvmT1 - swOvmT2) > coef->uwPWMMinSample1Pu) { out->uwSampleArea = IgnoreNone; out->uwRdsonTrig = 129; } else { if (swOvmT1 > coef->uwPWMMinSample1Pu) { switch (uwSector) { case 3: out->uwSampleArea = IgnoreA; break; case 1: out->uwSampleArea = IgnoreB; break; case 5: out->uwSampleArea = IgnoreB; break; case 4: out->uwSampleArea = IgnoreC; break; case 6: out->uwSampleArea = IgnoreC; break; case 2: out->uwSampleArea = IgnoreA; break; default: out->uwSampleArea = IgnoreNone; break; } out->uwRdsonTrig = swPWMPRD3 + coef->uwSampleSteadyCt; } else { switch (uwSector) { case 3: out->uwSampleArea = IgnoreAB; break; case 1: out->uwSampleArea = IgnoreAB; break; case 5: out->uwSampleArea = IgnoreBC; break; case 4: out->uwSampleArea = IgnoreBC; break; case 6: out->uwSampleArea = IgnoreAC; break; case 2: out->uwSampleArea = IgnoreAC; break; default: out->uwSampleArea = IgnoreNone; break; } out->uwRdsonTrig = swPWMPRD2 + coef->uwSampleSteadyCt; } } } else { //do nothing } } /************************************************************************ Local Functions: N/A ************************************************************************/ /************************************************************************ Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd. All rights reserved. ************************************************************************/ #ifdef _PWM_C_ #undef _PWM_C_ #endif /************************************************************************ End of this File (EOF)! Do not put anything after this part! ************************************************************************/