//---------------------------------------------------------------------------------- // FILE: HVPSFB-Main.C // // Description: Peak current mode control of a phase shifted full bridge // // Version: 1.0 // // Target: TMS320F2802x(PiccoloA) // //---------------------------------------------------------------------------------- // Copyright Texas Instruments © 2004-2009 //---------------------------------------------------------------------------------- // Revision History: //---------------------------------------------------------------------------------- // Date | Description / Status //---------------------------------------------------------------------------------- // 18 Apr 2011 - Peak Current Mode Controlled Phase Shifted Full bridge (HN) //---------------------------------------------------------------------------------- // // PLEASE READ - Useful notes about this Project // Although this project is made up of several files, the most important ones are: // "{ProjectName}-Main.C" - this file // - Application Initialization, Peripheral config, // - Application management // - Slower background code loops and Task scheduling // "{ProjectName}-DevInit_F28xxx.C // - Device Initialization, e.g. Clock, PLL, WD, GPIO mapping // - Peripheral clock enables // - DevInit file will differ per each F28xxx device series, e.g. F280x, F2833x, // "{ProjectName}-DPL-ISR.asm // - Assembly level library Macros and any cycle critical functions are found here // "{ProjectName}-Settings.h" // - Global defines (settings) project selections are found here // - This file is referenced by both C and ASM files. // Code is made up of sections, e.g. "FUNCTION PROTOTYPES", "VARIABLE DECLARATIONS" ,..etc // each section has FRAMEWORK and USER areas. // FRAMEWORK areas provide useful ready made "infrastructure" code which for the most part // does not need modification, e.g. Task scheduling, ISR call, GUI interface support,...etc // USER areas have functional example code which can be modified by USER to fit their appl. // // Code can be compiled with various build options (Incremental Builds IBx), these // options are selected in file "{ProjectName}-Settings.h". Note: "Rebuild All" compile // tool bar button must be used if this file is modified. //---------------------------------------------------------------------------------- #include "HVPSFB-Settings.h" #include "PeripheralHeaderIncludes.h" #include "DSP2802x_EPWM_defines.h" #include "DPlib.h" #include "IQmathLib.h" //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // FUNCTION PROTOTYPES //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% void DeviceInit(void); #ifdef FLASH void InitFlash(); #endif void MemCopy(); void DeviceInit(void); void SCIA_Init(); void SerialHostComms(); void InitFlash(); interrupt void ISR_Temp(void); //--------------------------------------------------------------- // System Defines //--------------------------------------------------------------- #define PWM_PRD (60000/200) // Period count = 300 corresponding to 100 KHz @ 60 MHz (Up-Down count mode) #define CP_MIN_THRESHOLD 25600 // 400W = 400*2^6 #define CP_HI_THRESHOLD 26880 // 420W = 420*2^6 #define CP_MID_THRESHOLD 26240 // 410W = 410*2^6 #define CC_MIN_THRESHOLD 4480 // 35A = 35*2^7 #define CC_HI_THRESHOLD 4864 // 38A = 38*2^7 #define CC_MID_THRESHOLD 4608 // 36A = 36*2^7 #define UV_THRESHOLD 8192 // 8V = 8*2^10 //-------------------------------- DPLIB -------------------------------------------- void PWMDRV_PSFB_PCMC_CNF(int16 n, int16 period, int16 SR_Enable, int16 Comp2_Prot); void ADC_SOC_CNF(int ChSel[], int Trigsel[], int ACQPS[], int IntChSel, int mode); extern void DacDrvCnf(int16 n, int16 DACval, int16 DACsrc, int16 RAMPsrc, int16 Slope_initial); // -------------------------------- FRAMEWORK -------------------------------------- // State Machine function prototypes //---------------------------------------------------------------------------------- // Alpha states void A0(void); //state A0 void B0(void); //state B0 void C0(void); //state C0 // A branch states void A1(void); //state A1 void A2(void); //state A2 void A3(void); //state A3 void A4(void); //state A4 // B branch states void B1(void); //state B1 void B2(void); //state B2 void B3(void); //state B3 void B4(void); //state B4 // C branch states void C1(void); //state C1 void C2(void); //state C2 void C3(void); //state C3 void C4(void); //state C4 // Variable declarations void (*Alpha_State_Ptr)(void); // Base States pointer void (*A_Task_Ptr)(void); // State pointer A branch void (*B_Task_Ptr)(void); // State pointer B branch void (*C_Task_Ptr)(void); // State pointer C branch //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // VARIABLE DECLARATIONS - GENERAL //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // -------------------------------- FRAMEWORK -------------------------------------- int16 VTimer0[4]; // Virtual Timers slaved of CPU Timer 0 (A events) int16 VTimer1[4]; // Virtual Timers slaved of CPU Timer 1 (B events) int16 VTimer2[4]; // Virtual Timers slaved of CPU Timer 2 (C events) int16 SerialCommsTimer; int16 CommsOKflg; extern Uint16 *RamfuncsLoadStart, *RamfuncsLoadEnd, *RamfuncsRunStart; // Used for ADC Configuration int ChSel[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; int ACQPS[16] = {8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8}; int TrigSel[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // ---------------------------------- USER ----------------------------------------- // ---------------------------- DPLIB Net Pointers --------------------------------- // Declare net pointers that are used to connect the DP Lib Macros here // ADCDRV_4ch extern volatile long *ADCDRV_4ch_RltPtrA; extern volatile long *ADCDRV_4ch_RltPtrB; extern volatile long *ADCDRV_4ch_RltPtrC; extern volatile long *ADCDRV_4ch_RltPtrD; // ADCDRV_1ch extern volatile long *ADCDRV_1ch_Rlt2; // Instance #1 extern volatile long *ADCDRV_1ch_Rlt3; // Instance #2 extern volatile long *ADCDRV_1ch_Rlt9; // Instance #3 extern volatile long *CNTL_2P2Z_Ref1, *CNTL_2P2Z_Out1, *CNTL_2P2Z_Fdbk1; extern volatile long *CNTL_2P2Z_Ref2, *CNTL_2P2Z_Out2, *CNTL_2P2Z_Fdbk2; extern volatile long *CNTL_2P2Z_Coef1, *CNTL_2P2Z_Coef2; // DACRAMPDRV extern volatile long *DACDRV_RAMP_In1; // ---------------------------- DPLIB Variables --------------------------------- // Declare the net variables being used by the DP Lib Macro here volatile long Adc_VavgBus[5]; // Used as consecutive addresses for ADC Vout conversion results #pragma DATA_SECTION(Adc_VavgBus, "ADCDRV_4ch_Section"); // Output terminal 1 volatile long Adc_Ifb, Adc_Vfbin, Adc_Iout; volatile long Vref = 0; // FB Set Voltage volatile long Iref = 0; // FB Current Loop Command volatile long Vfb_slew_temp = 0; // Temp variable: used only if implementing // slew rate control in the slower state machine volatile long VfbSetSlewed = 4187136; // Slewed set point for the FB voltage loop - start from 4V volatile long VfbSlewRate = 25600; // FB Slew rate adjustment int16 phase, dbAtoP_leg = 20, dbPtoA_leg = 20; // FB Phase command and Dead band // adjust for the right and left legs int16 Slope = 40, SR_mode = 2, SR_old=2; int16 No_2p2z = 0; // Used to disable 2P2Z execution when control loop coefficients are being changed int16 trig_up = 74, trig_dwn = (PWM_PRD-68); // Used to trigger ISR in Up-Count and Down-Count int16 range = 0, auto_DB = 1; // Used to adjust DB based on load conditions int16 input_good = 0, start_flag = 0; // Used for soft-start ad shut-down int16 SR_DB = -3; // Used to adjust SR timing if needed int16 sub_adj = 0; // Used to compensate for offsets in Iout reading int16 Fault_isr = 0, CC_flag = 0, CP_flag = 0; // Fault ISR counter, flags to keep track of constant current and constant power operations int16 CP_adjust1=2, CP_adjust = 2; // Used to implement constant power algorithm int16 UV_Shutdown = 0; // Under voltage shutdown flag int16 CC_Enable = 0, CP_Enable = 0; // CC and CP function enable int16 CC_Enable_safe = 0, CP_Enable_safe = 0; volatile long Avg_Vout = 0, Avg_tmp = 0; // Used for calculating average of output voltage over one switching cycle (8x oversampling) int16 Iout_prev = 0, Iout_diff = 0; // Used for fast dead-band adjustment for big load transients int16 Auto_Run = 1; // Stand-alone operation #pragma DATA_SECTION(CNTL_2P2Z_CoefStruct1, "CNTL_2P2Z_Coef"); #pragma DATA_SECTION(CNTL_2P2Z_CoefStruct2, "CNTL_2P2Z_Coef"); struct CNTL_2P2Z_CoefStruct CNTL_2P2Z_CoefStruct1; struct CNTL_2P2Z_CoefStruct CNTL_2P2Z_CoefStruct2; long Pgain, Igain, Dgain, Dmax; int16 Ipri_trip = 16925; // Programmable overcurrent shut-down level via on-chip comparator and DAC int16 Pgain_Gui = 648, Igain_Gui = 64, Dgain_Gui = 0; // PID gains for the voltage loop (Values can be controlled from CCS or GUI) int16 b2_Gui=0, b1_Gui=-10945, b0_Gui=12412, a2_Gui=0, a1_Gui=1024, a0_Gui; // 2P2Z coefficients for the voltage loop (Values can be controlled directly from CCS or from GUI by poles and zeroes placement) int16 pid2p2z_Gui= 1, coeff_change = 1; // Flag for switching between PID and poles and zeroes based coeffiefients, Flag to indicate change of coefficients // System Flags int16 FaultFlg; // Fault flag set on over current or output undervoltage conditions //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // VARIABLE DECLARATIONS - CCS WatchWindow / GUI support //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // -------------------------------- FRAMEWORK -------------------------------------- //GUI support variables // sets a limit on the amount of external GUI controls - increase as necessary int16 *varSetTxtList[64]; //64 textbox controlled variables int16 *varSetBtnList[16]; //16 button controlled variables int16 *varSetSldrList[16]; //16 slider controlled variables int16 *varGetList[16]; //16 variables sendable to GUI int16 *arrayGetList[16]; //16 arrays sendable to GUI // ---------------------------------- USER ----------------------------------------- // Monitor ("Get") // Display as: int16 Gui_Vfbin; // Q5 int16 Gui_Ifb; // Q12 int16 Gui_Vfbout; // Q10 int16 Gui_Iout; // Q7 int16 Gui_VfbSet = 1024; // Q10 int16 Gui_IfbSet = 614; // Q12 -- Build 1 Only - 0.15A int16 Gui_Pout = 0; // Q6 //Scaling Constants (values found via spreadsheet) int16 K_Vfbin; // Q15 int16 K_Ifb; // Q15 int16 K_Vfbout; // Q15 int16 K_Iout; // Q15 int16 iK_Ifb; // Q14 int16 iK_Vfbout; // Q14 // Variables for background support only (no need to access) int16 i; // common use incrementer int16 HistPtr, temp_Scratch; int16 temp_ChNum, temp_Iout; int16 Vset[NumChannels+1]; // Per Unit (Q15) int16 Vmargin[NumChannels+1]; // Per Unit (Q15) // History arrays are used for Running Average calculation (boxcar filter) // Used for CCS display and GUI only, not part of control loop processing int16 Hist_Vfbin[HistorySize]; int16 Hist_Ifb[HistorySize]; int16 Hist_Vfbout[HistorySize]; int16 Hist_Iout[HistorySize]; int16 Mytimer1 = 0;//harry int16 BlueLedToggle = 0;//harry void main(void) { //================================================================================= // INITIALISATION - General //================================================================================= //-------------------------------- FRAMEWORK -------------------------------------- DeviceInit(); // Device Life support & GPIO SCIA_Init(); // Initalize the Serial Comms A peripheral // Only used if running from FLASH #ifdef FLASH // Copy time critical code and Flash setup code to RAM // The RamfuncsLoadStart, RamfuncsLoadEnd, and RamfuncsRunStart // symbols are created by the linker. Refer to the linker files. MemCopy((Uint16*)&RamfuncsLoadStart, (Uint16*)&RamfuncsLoadEnd, (Uint16*)&RamfuncsRunStart); // Call Flash Initialization to setup flash waitstates // This function must reside in RAM InitFlash(); // Call the flash wrapper init function #endif //(FLASH) // Timing sync for background loops // Timer period definitions found in PeripheralHeaderIncludes.h CpuTimer0Regs.PRD.all = mSec2; // A tasks CpuTimer1Regs.PRD.all = mSec5; // B tasks CpuTimer2Regs.PRD.all = mSec0_5; // C tasks // Tasks State-machine init Alpha_State_Ptr = &A0; A_Task_Ptr = &A1; B_Task_Ptr = &B1; C_Task_Ptr = &C1; VTimer0[0] = 0; VTimer1[0] = 0; VTimer1[1] = 0; VTimer2[0] = 0; CommsOKflg = 0; HistPtr = 0; // ---------------------------------- USER ----------------------------------------- //Configure Scaling Constants K_Vfbin = 21555; // 0.6578 in Q15 (see excel spreadsheet) K_Ifb = 27755; // 0.8470 in Q15 (see excel spreadsheet) K_Vfbout = 16411; // 0.5008 in Q15 (see excel spreadsheet) K_Iout = 17974; // 0.5485 in Q15 (see excel spreadsheet) iK_Ifb = 19343; // 1.1806 in Q14 (see excel spreadsheet) iK_Vfbout = 32714; // 1.9967 in Q14 (see excel spreadsheet) //================================================================================= // INITIALISATION - GUI connections //================================================================================= // Use this section only if you plan to "Instrument" your application using the // Microsoft C# freeware GUI Template provided by TI //"Set" variables //--------------------------------------- // assign GUI variable Textboxes to desired "setable" parameter addresses varSetTxtList[0] = &Slope; // Q0 varSetTxtList[1] = &Ipri_trip; // Q15 varSetTxtList[2] = &dbAtoP_leg; // Q15 varSetTxtList[3] = &dbPtoA_leg; // Q15 varSetTxtList[4] = &sub_adj; // Q15 varSetTxtList[5] = &b0_Gui; // I5Q10 varSetTxtList[6] = &b1_Gui; // I5Q10 varSetTxtList[7] = &b2_Gui; // I5Q10 varSetTxtList[8] = &a0_Gui; // I5Q10 varSetTxtList[9] = &a1_Gui; // I5Q10 varSetTxtList[10] = &a2_Gui; // I5Q10 varSetTxtList[11] = &coeff_change; // Q0 varSetTxtList[12] = &SR_mode; // Q0 // assign GUI Buttons to desired flag addresses varSetBtnList[0] = &auto_DB; varSetBtnList[1] = &pid2p2z_Gui; varSetBtnList[2] = &CC_Enable; varSetBtnList[3] = &CP_Enable; varSetSldrList[0] = &Gui_VfbSet; // Q10 varSetSldrList[1] = &Pgain_Gui; // Q26/67108 varSetSldrList[2] = &Igain_Gui; // Q26/67108 varSetSldrList[3] = &Dgain_Gui; // Q26/67108 varGetList[0] = &Gui_Vfbout; // Q10 varGetList[1] = &Gui_Vfbin; // Q5 varGetList[2] = &Gui_Ifb; // Q12 varGetList[3] = &Gui_Iout; // Q9 varGetList[4] = &FaultFlg; // varGetList[5] = &dbAtoP_leg; // varGetList[6] = &dbPtoA_leg; // varGetList[7] = &SR_mode; // varGetList[8] = &Gui_Pout; // varGetList[9] = &CC_flag; // varGetList[10] = &CP_flag; // varGetList[11] = &UV_Shutdown; // //--------------------------------------------------------------------------- //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // Incremental build options via Module connections to system Nets. //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% EALLOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; EDIS; //================================================================================== // INCREMENTAL BUILD OPTIONS - NOTE: select via ProjectSettings.h //================================================================================== // ---------------------------------- USER ----------------------------------------- //============================================================================== #if (INCR_BUILD == 1) // CMC check with constant I command + ADC feedback //============================================================= #define Vfb_outR AdcResult.ADCRESULT1 // #define IfbR AdcResult.ADCRESULT2 // #define Vfb_inR AdcResult.ADCRESULT3 // #define IoutR AdcResult.ADCRESULT9 // // Channel Selection for Cascaded Sequencer ChSel[0] = 0; // A0 - O/P Voltage - Dummy ChSel[1] = 0; //B // A0 - O/P Voltage ChSel[2] = 2; // A2 - Transformer Primary Current ChSel[3] = 9; // B1 - I/P Voltage ChSel[4] = 0; //C // A0 - O/P Voltage ChSel[5] = 0; // A0 - O/P Voltage - Dummy ChSel[6] = 0; //A // A0 - O/P Voltage ChSel[7] = 0; // A0 - O/P Voltage - Dummy ChSel[8] = 0; //D // A0 - O/P Voltage // ChSel[9] = 11; // B3 - Iout1 ChSel[9] = 12; // B4 - Iout2 TrigSel[0] = ADCTRIG_EPWM3_SOCA; // O/P Voltage sampling triggered by EPWM3 SOCA - Dummy TrigSel[1] = ADCTRIG_EPWM3_SOCA; //B // O/P Voltage sampling triggered by EPWM3 SOCA TrigSel[2] = ADCTRIG_EPWM3_SOCA; // Transformer Primary Current sampling triggered by EPWM3 SOCA TrigSel[3] = ADCTRIG_EPWM3_SOCA; // I/P Voltage sampling triggered by EPWM3 SOCA TrigSel[4] = ADCTRIG_EPWM3_SOCA; //C // O/P Voltage sampling triggered by EPWM3 SOCA TrigSel[5] = ADCTRIG_EPWM1_SOCA; // O/P Voltage sampling triggered by EPWM1 SOCA at CTR = ZRO or PRD - Dummy TrigSel[6] = ADCTRIG_EPWM1_SOCA; //A // O/P Voltage sampling triggered by EPWM1 SOCA at CTR = ZRO or PRD TrigSel[7] = ADCTRIG_EPWM3_SOCB; // O/P Voltage sampling triggered by EPWM3 SOCB at CMPB3 - Dummy TrigSel[8] = ADCTRIG_EPWM3_SOCB; //D // O/P Voltage sampling triggered by EPWM3 SOCB at CMPB3 TrigSel[9] = ADCTRIG_EPWM2_SOCA; // Iout triggered by EPWM2 SOCA EALLOW; AdcRegs.SOCPRICTL.bit.SOCPRIORITY = 9; // SOC0-8 are high priority EDIS; PWMDRV_PSFB_PCMC_CNF(1, PWM_PRD, 1, 1); // ePWM1 and ePWM2, Period=PWM_PRD, SR_Enable=1, Comp2_Prot=1 ADC_SOC_CNF(ChSel,TrigSel,ACQPS, 16, 0);// ACQPS=8, No ADC channel triggers an interrupt IntChSel > 15, // Mode= Start/Stop (0) DPL_Init(); // ASM ISR init DacDrvCnf(1, 1280, 1, 2, Slope); // Comp1, DACval = 1280(Initial), Slope compensation is used, // Ramp is PWM3 Synced, Initial Slope // Lib Module connection to "nets" //---------------------------------------- // ADC feedback connections ADCDRV_4ch_RltPtrA = &Adc_VavgBus[1]; ADCDRV_4ch_RltPtrB = &Adc_VavgBus[2]; ADCDRV_4ch_RltPtrC = &Adc_VavgBus[3]; ADCDRV_4ch_RltPtrD = &Adc_VavgBus[4]; ADCDRV_1ch_Rlt2 = &Adc_Ifb; ADCDRV_1ch_Rlt3 = &Adc_Vfbin; ADCDRV_1ch_Rlt9 = &Adc_Iout; // DAC connections DACDRV_RAMP_In1 = &Iref; // Controls the DAC reference voltage #endif // (INCR_BUILD == 1) //============================================================================== #if (INCR_BUILD == 2) // // Closed loop: CMC + Voltage loop + Slope Comp //============================================================= #define Vfb_outR AdcResult.ADCRESULT1 // #define IfbR AdcResult.ADCRESULT2 // #define Vfb_inR AdcResult.ADCRESULT3 // #define IoutR AdcResult.ADCRESULT9 // // Channel Selection for Cascaded Sequencer ChSel[0] = 0; // A0 - O/P Voltage - Dummy ChSel[1] = 0; //B // A0 - O/P Voltage ChSel[2] = 2; // A2 - Transformer Primary Current ChSel[3] = 9; // B1 - I/P Voltage ChSel[4] = 0; //C // A0 - O/P Voltage ChSel[5] = 0; // A0 - O/P Voltage - Dummy ChSel[6] = 0; //A // A0 - O/P Voltage ChSel[7] = 0; // A0 - O/P Voltage - Dummy ChSel[8] = 0; //D // A0 - O/P Voltage // ChSel[9] = 11; // B3 - Iout1 ChSel[9] = 12; // B4 - Iout2 TrigSel[0] = ADCTRIG_EPWM3_SOCA; // O/P Voltage sampling triggered by EPWM3 SOCA - Dummy TrigSel[1] = ADCTRIG_EPWM3_SOCA; //B // O/P Voltage sampling triggered by EPWM3 SOCA TrigSel[2] = ADCTRIG_EPWM3_SOCA; // Transformer Primary Current sampling triggered by EPWM3 SOCA TrigSel[3] = ADCTRIG_EPWM3_SOCA; // I/P Voltage sampling triggered by EPWM3 SOCA TrigSel[4] = ADCTRIG_EPWM3_SOCA; //C // O/P Voltage sampling triggered by EPWM3 SOCA TrigSel[5] = ADCTRIG_EPWM1_SOCA; // O/P Voltage sampling triggered by EPWM1 SOCA triggered at CTR = ZRO or PRD - Dummy TrigSel[6] = ADCTRIG_EPWM1_SOCA; //A // O/P Voltage sampling triggered by EPWM1 SOCA triggered at CTR = ZRO or PRD TrigSel[7] = ADCTRIG_EPWM3_SOCB; // O/P Voltage sampling triggered by EPWM3 SOCB triggered at CMPB3 - Dummy TrigSel[8] = ADCTRIG_EPWM3_SOCB; //D // O/P Voltage sampling triggered by EPWM3 SOCB triggered at CMPB3 TrigSel[9] = ADCTRIG_EPWM2_SOCA; // Iout triggered by EPWM2 SOCA // ADC channel conversion priority EALLOW; AdcRegs.SOCPRICTL.bit.SOCPRIORITY = 9; // SOC0-8 are high priority EDIS; // Configure PWM1 and PWM2 with TBPRD of 300 clock cycles PWMDRV_PSFB_PCMC_CNF(1, PWM_PRD, 1, 1); // ePWM1 and ePWM2, Period=PWM_PRD, SR_Enable=1, Comp2_Prot=1 ADC_SOC_CNF(ChSel,TrigSel,ACQPS, 16, 0);// ACQPS=8, No ADC channel triggers an interrupt IntChSel > 15, Mode= Start/Stop (0) // Digital Power (DP) library initialisation DPL_Init(); // Configure Comparator and DAC for peak current mode operation with internal ramp for slope compensation DacDrvCnf(1, 1280, 1, 2, Slope); // Comp1, DACval = 1280(Initial), Slope compensation is used, Ramp is PWM3 Synced, Initial Slope // Lib Module connection to "nets" //---------------------------------------- // ADC feedback connections ADCDRV_4ch_RltPtrA = &Adc_VavgBus[1]; ADCDRV_4ch_RltPtrB = &Adc_VavgBus[2]; ADCDRV_4ch_RltPtrC = &Adc_VavgBus[3]; ADCDRV_4ch_RltPtrD = &Adc_VavgBus[4]; ADCDRV_1ch_Rlt2 = &Adc_Ifb; ADCDRV_1ch_Rlt3 = &Adc_Vfbin; ADCDRV_1ch_Rlt9 = &Adc_Iout; // 2P2Z connections for the outer Voltage Loop CNTL_2P2Z_Ref1 = &VfbSetSlewed; // Slewed Voltage command CNTL_2P2Z_Out1 = &Iref; // Reference command to the current loop CNTL_2P2Z_Fdbk1 = &Avg_Vout; // Avg. FB O/P Voltage feedback CNTL_2P2Z_Coef1 = &CNTL_2P2Z_CoefStruct1.b2; // point to first coeff. // DAC connections DACDRV_RAMP_In1 = &Iref; // Controls the DAC reference voltage // Coefficients for Outer Voltage Loop // PID coefficients & Clamping (Q26) Dmax = _IQ24(0.25); Pgain = _IQ26(0.6479916); Igain = _IQ26(0.06399917); Dgain = _IQ26(0.0); // Coefficient init --- Coeeficient values in Q26 // Use IQ Maths to generate floating point values for the CLA CNTL_2P2Z_CoefStruct1.b2 = Dgain; // B2 CNTL_2P2Z_CoefStruct1.b1 = (Igain-Pgain-Dgain-Dgain); // B1 CNTL_2P2Z_CoefStruct1.b0 = (Pgain + Igain + Dgain); // B0 CNTL_2P2Z_CoefStruct1.a2 = 0.0; // A2 = 0 CNTL_2P2Z_CoefStruct1.a1 = _IQ26(1.0); // A1 = 1 CNTL_2P2Z_CoefStruct1.max = Dmax; //Clamp Hi CNTL_2P2Z_CoefStruct1.min = _IQ24(0.0); //Clamp Min #endif // (INCR_BUILD == 2) // Configure Comparator2 and DAC for over current protection DacDrvCnf(2, Ipri_trip, 0, 2, 0); // Comp2, DACval = Ipri_trip, DAC Source is DACval, Ramp Source = don't care, Slope = don't care FaultFlg = 0; EPwm1Regs.TZCLR.bit.OST = 1; // Clear any spurious OC trip EPwm2Regs.TZCLR.bit.OST = 1; // Clear any spurious OC trip EALLOW; GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // 0=GPIO, 1=EPWM1A, 2=Resv, 3=Resv GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; // 0=GPIO, 1=EPWM1B, 2=SPISIMO-D, 3=Resv GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1; // 0=GPIO, 1=EPWM2A, 2=Resv, 3=Resv GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 1; // 0=GPIO, 1=EPWM2B, 2=SPISOMI-D, 3=Resv GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 1; // 0=GPIO, 1=EPWM4A, 2=SYNCI, 3=SYNCO GpioCtrlRegs.GPAMUX1.bit.GPIO7 = 1; // 0=GPIO, 1=EPWM4B, 2=SPISTE-D, 3=ECAP2 //All enabled ePWM module clocks are started with the first rising edge of TBCLK aligned SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; EDIS; //================================================================================= // INTERRUPT & ISR INITIALISATION (best to run this section after other initialisation) //================================================================================= //Also Set the appropriate # define's in the {ProjectName}-Settings.h //to enable interrupt management in the ISR EALLOW; PieVectTable.EPWM1_INT = &DPL_ISR; // Map Interrupt EDIS; PieCtrlRegs.PIEIER3.bit.INTx1 = 1; // PIE level enable, Grp3 / Int1 EPwm1Regs.ETSEL.bit.INTSEL = ET_CTRU_CMPA; // INT on CMPA event EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT every event // Enable Peripheral, global Ints and higher priority real-time debug events: IER |= M_INT3; EINT; // Enable Global interrupt INTM ERTM; // Enable Global realtime interrupt DBGM // EALLOW; // Backgound Loop for(;;) { // State machine entry & exit point //=========================================================== (*Alpha_State_Ptr)(); // jump to an Alpha state (A0,B0,...) //=========================================================== // Fast dead-band adjustment for large load transients Iout_diff = IoutR - Iout_prev; if (Iout_diff>292 || Iout_diff<(-292)) //12-bit ADC result corresponding to a change of 10A on Iout ~ 292d C1(); Iout_prev = IoutR; } } //END MAIN CODE //================================================================================= // STATE-MACHINE SEQUENCING AND SYNCRONIZATION //================================================================================= //--------------------------------- FRAMEWORK ------------------------------------- void A0(void) { // loop rate synchronizer for A-tasks if(CpuTimer0Regs.TCR.bit.TIF == 1) { CpuTimer0Regs.TCR.bit.TIF = 1; // clear flag //----------------------------------------------------------- (*A_Task_Ptr)(); // jump to an A Task (A1,A2,A3,...) //----------------------------------------------------------- if (Mytimer1 == 500) { Mytimer1 = 0; BlueLedToggle = 1; } else Mytimer1++; VTimer0[0]++; // virtual timer 0, instance 0 (spare) } Alpha_State_Ptr = &B0; // Comment out to allow only A tasks } void B0(void) { // loop rate synchronizer for B-tasks if(CpuTimer1Regs.TCR.bit.TIF == 1) { CpuTimer1Regs.TCR.bit.TIF = 1; // clear flag //----------------------------------------------------------- (*B_Task_Ptr)(); // jump to a B Task (B1,B2,B3,...) //----------------------------------------------------------- VTimer1[0]++; // virtual timer 1, instance 0 VTimer1[1]++; // virtual timer 1, instance 1 (used by DSP280xx_SciCommsGui.c) } Alpha_State_Ptr = &C0; // Allow C state tasks } void C0(void) { // loop rate synchronizer for C-tasks if(CpuTimer2Regs.TCR.bit.TIF == 1) { CpuTimer2Regs.TCR.bit.TIF = 1; // clear flag //----------------------------------------------------------- (*C_Task_Ptr)(); // jump to a C Task (C1,C2,C3,...) //----------------------------------------------------------- VTimer2[0]++; //virtual timer 2, instance 0 (spare) } Alpha_State_Ptr = &A0; // Back to State A0 } //================================================================================= // A - TASKS //================================================================================= //-------------------------------------------------------- void A1(void) // Control Coefficient re-calculations //===================================================================== { // Fault management if (CC_flag == 1 || CP_flag == 1) { if (Gui_Vfbout < UV_THRESHOLD) // If output voltage < UV threshold when operating in CC or CP mode - then Shutdown { EALLOW; EPwm1Regs.TZFRC.bit.OST = 1; EDIS; UV_Shutdown = 1; } } if ( (*ePWM[1]).TZFLG.bit.OST == 1 ) { FaultFlg = 1; DINT; // Disable Global interrupt EALLOW; PieVectTable.EPWM1_INT = &ISR_Temp; // Temporary Interrupt to service pending interrupts EPwm1Regs.ETSEL.bit.INTEN = 0; //Disable interrupt at the peripheral level EINT; // Enable Global interrupt INTM asm (" NOP"); asm (" NOP"); asm (" NOP"); asm (" NOP"); asm (" NOP"); // Wait 5 cycles for any pending interrupts to be serviced DINT; // Disable Global interrupt PieVectTable.EPWM1_INT = &DPL_ISR; // Interrupt re-mapped // EDIS; PieCtrlRegs.PIEIER3.bit.INTx1 = 0; // PIE level Disable, Grp3 / Int1 PieCtrlRegs.PIEIFR3.bit.INTx1 = 0; // Clear IFR register // Acknowledge this interrupt to receive more interrupts from group 3 PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; EINT; // Enable Global interrupt INTM EPwm2Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // Initial Config EPwm2Regs.TZCTL.bit.TZB = TZ_FORCE_LO; EPwm4Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // Initial Config EPwm4Regs.TZCTL.bit.TZB = TZ_FORCE_LO; EPwm2Regs.TZFRC.bit.OST = 1; // Initial Config EPwm4Regs.TZFRC.bit.OST = 1; EDIS; } else FaultFlg = 0; Pgain = Pgain_Gui*67108; // Q26 Igain = Igain_Gui*67108; // Q26 Dgain = Dgain_Gui*67108; // Q26 if (coeff_change == 1) { No_2p2z = 1; // Used to disable 2P2Z execution when coefficients are being changed if (pid2p2z_Gui == 0) { // Voltage loop coefficient update CNTL_2P2Z_CoefStruct1.b2 = Dgain; // B2 CNTL_2P2Z_CoefStruct1.b1 = (Igain - Pgain - Dgain - Dgain); // B1 CNTL_2P2Z_CoefStruct1.b0 = (Pgain + Igain + Dgain); // B0 CNTL_2P2Z_CoefStruct1.a2 = 0.0; // A2 = 0 CNTL_2P2Z_CoefStruct1.a1 = _IQ26(1.0); // A1 = 1 // CNTL_2P2Z_CoefStruct1.max =Dmax; //Clamp Hi // CNTL_2P2Z_CoefStruct1.min =_IQ24(0.0); //Clamp Min } else { CNTL_2P2Z_CoefStruct1.b2 = b2_Gui*65536; // B2 - I5Q10 scaled to I5Q26 CNTL_2P2Z_CoefStruct1.b1 = b1_Gui*65536; // B1 CNTL_2P2Z_CoefStruct1.b0 = b0_Gui*65536; // B0 CNTL_2P2Z_CoefStruct1.a2 = a2_Gui*65536; // A2 CNTL_2P2Z_CoefStruct1.a1 = a1_Gui*65536; // A1 // CNTL_2P2Z_CoefStruct1.max =Dmax; //Clamp Hi // CNTL_2P2Z_CoefStruct1.min =_IQ24(0.0); //Clamp Min } No_2p2z = 0; coeff_change = 0; } EALLOW; Comp2Regs.DACVAL.bit.DACVAL = ((Ipri_trip)>>5); // DAC Value is in Q10 Comp1Regs.RAMPDECVAL_SHDW = Slope; EDIS; //------------------- A_Task_Ptr = &A2; //------------------- } //===================================================================== void A2(void) // Slew Rate, SCI GUI //----------------------------------------------------------------- { // This is an example code for implementing the slew rate control in // a slower state machine instead of implementing it in the ISR. // VfbSlewRate should be set as a positive value Vfb_slew_temp = Vref - VfbSetSlewed; if (Vfb_slew_temp >= VfbSlewRate) // Positive Command { VfbSetSlewed = VfbSetSlewed + VfbSlewRate; } else { if ((-1)*(Vfb_slew_temp) >= VfbSlewRate) // Negative Command { VfbSetSlewed = VfbSetSlewed - VfbSlewRate; } } SerialHostComms(); //------------------- A_Task_Ptr = &A3; // To make task A3 active, change &A1 to &A3 //------------------- } //======================================================================= void A3(void) // SPARE (not active) //======================================================================= { if (BlueLedToggle == 1)//Mytimer1==500) { GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1; Mytimer1=0; BlueLedToggle = 0; } //----------------- A_Task_Ptr = &A1; // To make task A4 active, change &A1 to &A4 //----------------- } /* //======================================================================= void A3(void) // SPARE (not active) //======================================================================= { //----------------- A_Task_Ptr = &A1; // To make task A4 active, change &A1 to &A4 //----------------- } //===================================================================== void A4(void) // SPARE (not active) //===================================================================== { //----------------- A_Task_Ptr = &A1; // After Task A4, start over with task A1 //----------------- }*/ //%%%%%%%%%%%%%%% B-Tasks: %%%%%%%%%%%%%%%%%%%%%%%%% //===================================================================== void B1(void) // Voltage and Current Dashboard measurements //===================================================================== { // Voltage measurement calculated by: // Gui_Vfbin = VfbinAvg * K_Vfbin, where VfbinAvg = sum of 8 Vfb_inR samples // Gui_Vfbout = VfboutAvg * K_Vfbout, where VfboutAvg = sum of 8 Vfb_outR samples HistPtr++; if (HistPtr >= 8) HistPtr = 0; // BoxCar Averages - Input Raw samples into History arrays //---------------------------------------------------------------- Hist_Vfbin[HistPtr] = Vfb_inR; // Raw ADC result (Q12) temp_Scratch=0; for(i=0; i> 15; // (Q15 * Q15)>>15 = Q15 // BoxCar Averages - Input Raw samples into History arrays //---------------------------------------------------------------- Hist_Vfbout[HistPtr] = Vfb_outR; // Raw ADC result (Q12) temp_Scratch=0; for(i=0; i> 15; // (Q15 * Q15)>>15 = Q15 // Voltage Meas //---------------------------------------------------------------- // view following variables in Watch Window as: // Gui_Vfbin = Q5 // Gui_Vfbout = Q10 // Current measurement calculated by: // Gui_Ifb = IfbAvg * K_Ifb, where IfbAvg = sum of 8 IfbR samples //BoxCar Averages - Input Raw samples into History arrays Hist_Ifb[HistPtr] = IfbR; // Raw ADC result (Q12) temp_Scratch=0; for(i=0; i> 15; // (Q15 * Q15)>>15 = Q15 Hist_Iout[HistPtr] = IoutR; // Raw ADC result (Q12) temp_Scratch=0; for(i=0; i> 15) - sub_adj; // (Q15 * Q15)>>15 = Q15 (Offset Adjust) if (temp_Scratch < 0) temp_Scratch = 0; Gui_Iout = temp_Scratch; // Current Meas //---------------------------------------------------------------- // view following variables in Watch Window as: // Gui_Ifb = Q12 // Voltage setting calculated by: // Vref = Gui_VfbSet * iK_Vfbout, where iK_Vfbout = 1/K_Vfbout (i.e. inverse K_Vfbout) // view and set following variable in Watch Window as: // Gui_VfbSet = Q10 (Used as Q15 below) Vref = ( (long) Gui_VfbSet * (long) iK_Vfbout ) >> 5; // (Q15 * Q14) >> 5 = Q24 #if (INCR_BUILD == 1) // Current setting calculated by: // Iref = Gui_IfbSet * iK_Ifb, where iK_Ifb = 1/K_Ifb (i.e. inverse K_Ifb) // view and set following variable in Watch Window as: // Gui_IfbSet = Q12 (Used as Q15 below) if (Gui_IfbSet < 614) // Gui_IfbSet >= 0.15A Gui_IfbSet = 614; Iref = ( (long) Gui_IfbSet * (long) iK_Ifb ) >> 5; // (Q15 * Q14) >> 5 = Q24 #endif B_Task_Ptr = &B1; //----------------- } /* //===================================================================== void B2(void) // SPARE //===================================================================== { //----------------- B_Task_Ptr = &B1; //----------------- } //===================================================================== void B3(void) // SPARE (not active) //===================================================================== { //----------------- B_Task_Ptr = &B1; //----------------- } //===================================================================== void B4(void) // SPARE (not active) //===================================================================== { //----------------- B_Task_Ptr = &B1; //----------------- } */ //%%%%%%%%%%%%%%% C-Tasks: %%%%%%%%%%%%%%%%%%%%%%%%% //===================================================================== //===================================================================== void C1(void) //===================================================================== { if (auto_DB == 1) { switch (range) { case 0: if (Gui_Iout < 640) // 5A { /* if (dbAtoP_leg<36) dbAtoP_leg++; else { if (dbAtoP_leg>36) dbAtoP_leg--; } if (dbPtoA_leg<44) dbPtoA_leg++; else { if (dbPtoA_leg>44) dbPtoA_leg--; }*/ dbAtoP_leg = 36; dbPtoA_leg = 44; range = 0; } else range = 1; break; case 1: if (Gui_Iout > 512 && Gui_Iout < 1024) // 4A & 8A { /* if (dbAtoP_leg<32) dbAtoP_leg++; else { if (dbAtoP_leg>32) dbAtoP_leg--; } if (dbPtoA_leg<42) dbPtoA_leg++; else { if (dbPtoA_leg>42) dbPtoA_leg--; }*/ dbAtoP_leg = 32; dbPtoA_leg = 42; range = 1; } else { if (Gui_Iout > 1023) range = 2; else range = 0; } break; case 2: if (Gui_Iout > 896 && Gui_Iout < 1408) // 7A & 11A { /* if (dbAtoP_leg<27) dbAtoP_leg++; else { if (dbAtoP_leg>27) dbAtoP_leg--; } if (dbPtoA_leg<22) dbPtoA_leg++; else { if (dbPtoA_leg>22) dbPtoA_leg--; }*/ dbAtoP_leg = 27; dbPtoA_leg = 22; range = 2; } else { if (Gui_Iout > 1407) range = 3; else range = 0; } break; case 3: if (Gui_Iout > 1280 && Gui_Iout < 1792) // 10A & 14A { /* if (dbAtoP_leg<22) dbAtoP_leg++; else { if (dbAtoP_leg>22) dbAtoP_leg--; } if (dbPtoA_leg<22) dbPtoA_leg++; else { if (dbPtoA_leg>22) dbPtoA_leg--; }*/ dbAtoP_leg = 22; dbPtoA_leg = 22; range = 3; } else { if (Gui_Iout > 1791) range = 4; else range = 0; } break; case 4: if (Gui_Iout > 1664 && Gui_Iout < 2176) // 13A & 17A { /* if (dbAtoP_leg<20) dbAtoP_leg++; else { if (dbAtoP_leg>20) dbAtoP_leg--; } if (dbPtoA_leg<21) dbPtoA_leg++; else { if (dbPtoA_leg>21) dbPtoA_leg--; }*/ dbAtoP_leg = 20; dbPtoA_leg = 21; range = 4; } else { if (Gui_Iout > 2175) range = 5; else range = 0; } break; case 5: if (Gui_Iout > 2048 && Gui_Iout < 2560) // 16A & 20A { /* if (dbAtoP_leg<20) dbAtoP_leg++; else { if (dbAtoP_leg>20) dbAtoP_leg--; } if (dbPtoA_leg<18) dbPtoA_leg++; else { if (dbPtoA_leg>18) dbPtoA_leg--; }*/ dbAtoP_leg = 20; dbPtoA_leg = 18; range = 5; } else { if (Gui_Iout > 2559) range = 6; else range = 0; } break; case 6: if (Gui_Iout > 2432 && Gui_Iout < 2944) // 19A & 23A { /* if (dbAtoP_leg<18) dbAtoP_leg++; else { if (dbAtoP_leg>18) dbAtoP_leg--; } if (dbPtoA_leg<18) dbPtoA_leg++; else { if (dbPtoA_leg>18) dbPtoA_leg--; }*/ dbAtoP_leg = 18; dbPtoA_leg = 18; range = 6; } else { if (Gui_Iout > 2943) range = 7; else range = 0; } break; case 7: if (Gui_Iout > 2816 && Gui_Iout < 3328) // 22A & 26A { /* if (dbAtoP_leg<18) dbAtoP_leg++; else { if (dbAtoP_leg>18) dbAtoP_leg--; } if (dbPtoA_leg<14) dbPtoA_leg++; else { if (dbPtoA_leg>14) dbPtoA_leg--; }*/ dbAtoP_leg = 18; dbPtoA_leg = 14; range = 7; } else { if (Gui_Iout > 3327) range = 8; else range = 0; } break; case 8: if (Gui_Iout > 3200 && Gui_Iout < 4096) // 25A & 32A { /* if (dbAtoP_leg<16) dbAtoP_leg++; else { if (dbAtoP_leg>16) dbAtoP_leg--; } if (dbPtoA_leg<14) dbPtoA_leg++; else { if (dbPtoA_leg>14) dbPtoA_leg--; }*/ dbAtoP_leg = 16; dbPtoA_leg = 14; range = 8; } else { if (Gui_Iout > 4095) range = 9; else range = 0; } break; case 9: if (Gui_Iout > 3968 && Gui_Iout < 4864) // 31A & 38A { /* if (dbAtoP_leg<15) dbAtoP_leg++; else { if (dbAtoP_leg>15) dbAtoP_leg--; } if (dbPtoA_leg<13) dbPtoA_leg++; else { if (dbPtoA_leg>13) dbPtoA_leg--; }*/ dbAtoP_leg = 15; dbPtoA_leg = 13; range = 9; } else { if (Gui_Iout > 4863) range = 10; else range = 0; } break; case 10: if (Gui_Iout > 4736 && Gui_Iout < 5632) // 37A & 44A { /* if (dbAtoP_leg<14) dbAtoP_leg++; else { if (dbAtoP_leg>14) dbAtoP_leg--; } if (dbPtoA_leg<12) dbPtoA_leg++; else { if (dbPtoA_leg>12) dbPtoA_leg--; }*/ dbAtoP_leg = 14; dbPtoA_leg = 12; range = 10; } else { if (Gui_Iout > 5631) range = 11; else range = 0; } break; case 11: if (Gui_Iout > 5504) // 43A { /* if (dbAtoP_leg<12) dbAtoP_leg++; else { if (dbAtoP_leg>12) dbAtoP_leg--; } if (dbPtoA_leg<12) dbPtoA_leg++; else { if (dbPtoA_leg>12) dbPtoA_leg--; }*/ dbAtoP_leg = 12; dbPtoA_leg = 12; range = 11; } else range = 0; break; } } EPwm1Regs.DBRED = dbPtoA_leg; EPwm1Regs.DBFED = dbPtoA_leg; if(Auto_Run == 1) //----------------- C_Task_Ptr = &C2; //----------------- else //----------------- C_Task_Ptr = &C1; //----------------- } //===================================================================== void C2(void) // SPARE (not active) //===================================================================== { if (Gui_Vfbin > 11200 && Gui_Vfbin < 13440) // 350= 100) // Input has been good for 100*(C2 task execution rate) { if (start_flag == 0) { VfbSetSlewed = 2093568; // Start ramping up from 2V (Q24) Gui_VfbSet = 12.2*1024; // Desired Output * 2^10 start_flag = 1; } } else { input_good++; if (input_good == 80) { EPwm1Regs.TZCLR.bit.OST = 1; // Clear any spurious OC trip EPwm2Regs.TZCLR.bit.OST = 1; // Clear any spurious OC trip EPwm4Regs.TZCLR.bit.OST = 1; // Clear any spurious OC trip } } } else { input_good = 0; Gui_VfbSet = 2*1024; //2V Dmax = _IQ24(0.25); CNTL_2P2Z_CoefStruct1.max = Dmax; start_flag = 0; } Gui_Pout = ((long)(Gui_Iout) * (long)(Gui_Vfbout))>>11; // Q7*Q10>>11. Gui_Pout in Q6 if (start_flag == 1) { if (Gui_Iout > CC_MIN_THRESHOLD && CC_Enable == 1) { if (Gui_Iout > CC_HI_THRESHOLD) // Too high - needs faster response { Dmax = (Dmax<=_IQ24(0.1))?_IQ24(0.1):(Dmax - _IQ24(0.0003)); //Clamp Dmax to a minimum of 0.1 CNTL_2P2Z_CoefStruct1.max = Dmax; } else { if (Gui_Iout > CC_MID_THRESHOLD) { Dmax = (Dmax<=_IQ24(0.1))?_IQ24(0.1):(Dmax - _IQ24(0.0001)); //Clamp Dmax to a minimum of 0.1 CNTL_2P2Z_CoefStruct1.max = Dmax; } } CC_flag = 1; CP_flag = 0; } else { if (Dmax < _IQ24(0.734375)) { Dmax = Dmax + _IQ24(0.01); CNTL_2P2Z_CoefStruct1.max = Dmax; } else { Dmax = _IQ24(0.734375); CNTL_2P2Z_CoefStruct1.max = Dmax; } CC_flag = 0; } if (CP_Enable == 1) { if (Gui_Pout > CP_MIN_THRESHOLD) { if (Gui_Pout > CP_HI_THRESHOLD) Gui_VfbSet = (Gui_VfbSet>8192)?(Gui_VfbSet - CP_adjust*4):8192; // Reduce Vout command at a faster rate. Clamped to 8192 i.e. 8V else { if (Gui_Pout > CP_MID_THRESHOLD) Gui_VfbSet = (Gui_VfbSet>8192)?(Gui_VfbSet - CP_adjust):8192; // Reduce Vout command. Clamped to 8192 i.e. 8V } CP_flag = (CC_flag==1)?0:1; } else { if (CC_flag == 0) Gui_VfbSet = (Gui_VfbSet<12492)?(Gui_VfbSet + CP_adjust1):12492; // Increase Vout command slowly. Clamp Max to 12.2V CP_flag = 0; } } else { Gui_VfbSet = 12.2*1024; CP_flag = 0; } } else // start_flag = 0. FB is disabled, re-intialise Dmax to a low value { Dmax = _IQ24(0.25); CNTL_2P2Z_CoefStruct1.max = Dmax; } //----------------- C_Task_Ptr = &C1; //----------------- } /* //===================================================================== void C2(void) // SPARE (not active) //===================================================================== { //----------------- C_Task_Ptr = &C1; //----------------- }*/ interrupt void ISR_Temp(void) { Fault_isr++; asm(" IRET"); // Return from interrupt }