This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Trip Zone software force in 28032

Other Parts Discussed in Thread: CONTROLSUITE

I want to use one shot software force trip zone to do overcurrent protection. I use software to force the flag setting, but not sure if I still need to set the trip zone source, like TZ1,2,3 or others. Can anyone give some hints? My code is shown below,

PWM setting part:

EALLOW;
EPwm4Regs.TZCTL.bit.TZA = 1; // EPWM4A forces to high
EPwm4Regs.TZSEL.bit.OSHT5 = 1; // /TZ5 is used as one shot trip source, but actually software trip
EPwm4Regs.TZCLR.bit.OST = 1; // clear trip zone flags
EDIS;

EALLOW;
EPwm5Regs.TZCTL.bit.TZA = 1; // EPWM5A forces to high
EPwm5Regs.TZSEL.bit.OSHT5 = 1; // /TZ5 is used as one shot trip source, but actually software trip
EPwm5Regs.TZCLR.bit.OST = 1; // clear trip zone flags
EDIS;

protection part:

void protection(float input, float max)
{
if (input > max)
{
EALLOW;
EPwm4Regs.TZFRC.bit.OST = 1;
EPwm5Regs.TZFRC.bit.OST = 1;   // inductor is disconnected from source and load, now connected to GND
EDIS;
}
}

  • Yi Shang,

    Your code should work as it is, however if you are only using software to force the trip you do not need to configure the TZSEL. Also, the trip zone flags affect the TZ interrupt in the PIE block, so if you're not using an interrupt you won't need to clear the TZ flags either. All you need for a software force is to initialize the TZA/B bits in TZCTL, and then write to the TZFRC register to force the event you want.

    The use of floating-point variables in the conditional check isn't going to be very efficient on this machine. For over-current protection I recommend using a comparator as the TZ source, rather than relying on software. That will be safer, and give you better and more deterministic timing between the OC event and the PWM trip.

    Regards,

    Richard
  • Hi Richard,

    Thanks for your clarification. Now I have better understanding of trip zone setting. So according to your advice, the conditional check with float variables for OC event may not respond quickly, is that right? Then as for comparator as the TZ source, does it refer to Digital Compare part in EPWM setting?

    Thanks,
    Yi
  • Yi,

    Yes, that's correct. The F2803x is a fixed-point machine so anytime you use true floating-point variables it will consume a lot of cycles to emulate that data type. There is a library called "IQ math" which allows you to port floating-point code onto F2803x quite efficiently, so you may want to look into that. However, in any case using software to force a PWM trip condition is not the best way of implementing current trip.

    What I was suggesting is an analogue comparator which monitors the inductor current relative to an adjustable threshold. The 28032 has three such integrated comparators which are intended to be used in this way. If you look in section 3.10 of the ePWM user's guide you'll find a configuration example for a peak current mode controlled buck converter which may be of interest:
    www.ti.com/.../spruge9e.pdf

    Using a hardware comparator in this way removes the software from the trip process so you have the fastest and most reliable trip action. You coulde implement it on a cycle-by-cycle basis as shown in the example, or use one-shot mode if you're interested in over-current protection.

    Regards,

    Richard
  • Richard,

    Thanks for your detailed explanation. I will follow your advice and look into OC protection using comparators. And besides the settings in EPWM as "peak current mode controlled buck converter" example, I suppose that DAC part setting is also needed, right?

    Thanks,
    Yi
  • Yi,

    Yes, that's correct.  Each comparator block contains an internal 10-bit DAC which you can optionally use to generate the trip threshold.  If peak current mode control is what you're doing, there is a ramp generator which you can use for slope compensation.

    Regards,

    Richard

  • Richard,

    I am using average current mode control and need OC protection. Can you give more hints on DAC setting together with the use of comparator? Or where else can I find similar examples? Because I only used ADC but have no idea with DAC part.

    Thanks,
    Yi
  • Yi,

    The comparator sub-system is documented in chapter 2 of the ADC user's guide:  http://www.ti.com/lit/ug/spruge5f/spruge5f.pdf

    It's pretty straightforward to configure and use the comparator + DAC for over-current protection only.  There is an example in the examples for this device in controlSUITE.  The example name is "epwm_dcevent_trip_comp".  This example will shut down PWM1 in response to an over-voltage condition at the comparator input.  

    I hope this helps.

    Regards,

    Richard

    //###########################################################################
    // Description:
    //! \addtogroup f2803x_example_list
    //! <h1>ePWM DC Event Trip Comparator (epwm_dcevent_trip_comp)</h1>
    //!
    //! In this example ePWM1 is configured for PWM Digital Compare Event
    //! Trip using Comparator1A and comparator1B pin inputs.
    //! DCAEVT1, DCBEVT1 events are triggered by increasing the voltage on
    //! COMP1B pin to be higher than that of COMP1A pin.
    //! In this example:
    //!    - ePWM1 has DCAEVT1 and DCBEVT1 as one shot trip sources
    //!            DCAEVT1 will pull EPWM1A high
    //!            DCBEVT1 will pull EPWM1B low
    //!
    //! Initially make the voltage level at COMP1A to be higher than that of COMP1B.
    //! Increase voltage on inverting side of comparator(COMP1B pin) to trigger
    //! a DCAEVT1, and DCBEVT1. ePWM1 will react to DCAEVT1 and DCBEVT1 as a 1 shot
    //! trip. View the EPWM1A/B waveforms on an oscilloscope to see the effect of
    //! the events.
    //!
    //! \b External \b Connections \n
    //!  - EPWM1A is on GPIO0
    //!  - EPWM1B is on GPIO1
    //!  - COMP1A is on ADCA2
    //!  - COMP1B is on ADCB2
    //!  - pull COMP1B to a higher voltage level than COMP1A.
    //
    //###########################################################################
    // $TI Release: F2803x C/C++ Header Files and Peripheral Examples V130 $
    // $Release Date: May  8, 2015 $
    // $Copyright: Copyright (C) 2009-2015 Texas Instruments Incorporated -
    //             http://www.ti.com/ ALL RIGHTS RESERVED $
    //###########################################################################
    
    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    
    // Prototype statements for functions found within this file.
    void InitEPwm1Example(void);
    __interrupt void epwm1_tzint_isr(void);
    
    // Global variables used in this example
    Uint32  EPwm1TZIntCount;
    Uint32  EPwm2TZIntCount;
    
    void main(void)
    {
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the DSP2803x_SysCtrl.c file.
       InitSysCtrl();
    
    // Step 2. Initialize GPIO:
    // This example function is found in the DSP2803x_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // InitGpio();  // Skipped for this example
    
    // For this case just init GPIO pins for ePWM1, ePWM2, and TZ pins
       InitEPwm1Gpio();
    
    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
       DINT;
    
    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the DSP2803x_PieCtrl.c file.
       InitPieCtrl();
    
    // Disable CPU interrupts and clear all CPU interrupt flags:
       IER = 0x0000;
       IFR = 0x0000;
    
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in DSP2803x_DefaultIsr.c.
    // This function is found in DSP2803x_PieVect.c.
       InitPieVectTable();
    
    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
       EALLOW;  // This is needed to write to EALLOW protected registers
       PieVectTable.EPWM1_TZINT = &epwm1_tzint_isr;
       EDIS;    // This is needed to disable write to EALLOW protected registers
    
    // Step 4. Initialize all the Device Peripherals:
    // Not required for this example
       EALLOW;
       SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;                 // Enable Clock to the ADC
       AdcRegs.ADCCTL1.bit.ADCBGPWD = 1;                     // Comparator shares the internal BG reference of the ADC, must be powered even if ADC is unused
       DELAY_US(1000L);                                      // Delay to allow BG reference to settle.
    
       SysCtrlRegs.PCLKCR3.bit.COMP1ENCLK = 1;               // Enable clock to the Comparator 1 block
       Comp1Regs.COMPCTL.bit.COMPDACEN = 1;                  // Power up Comparator 1 locally
       Comp1Regs.COMPCTL.bit.COMPSOURCE = 1;                 // Connect the inverting input to pin COMP1B
    ////////////////Uncomment following 2 lines to use DAC instead of pin COMP1B //////////////////
    //   Comp1Regs.COMPCTL.bit.COMPSOURCE = 0;              // Connect the inverting input to the internal DAC
    //   Comp1Regs.DACVAL.bit.DACVAL = 512;				    // Set DAC output to midpoint
    //////////////////////////////////////////////////////////////////////////////////////////////
       SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
       EDIS;
    
       InitEPwm1Example();
    
       EALLOW;
       SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
       EDIS;
    
    // Step 5. User specific code, enable interrupts
    // Initialize counters:
       EPwm1TZIntCount = 0;
    
    // Enable CPU INT3 which is connected to EPWM1-3 INT:
       IER |= M_INT2;
    
    // Enable EPWM INTn in the PIE: Group 2 interrupt 1-3
       PieCtrlRegs.PIEIER2.bit.INTx1 = 1;
    
    // Enable global Interrupts and higher priority real-time debug events:
       EINT;   // Enable Global interrupt INTM
       ERTM;   // Enable Global realtime interrupt DBGM
    
    // Step 6. IDLE loop. Just sit and loop forever (optional):
       for(;;)
       {
           __asm("          NOP");
       }
    }
    
    __interrupt void epwm1_tzint_isr(void)
    {
       EPwm1TZIntCount++;
    
    // Leave these flags set so we only take this
    // interrupt once
    //
    // EALLOW;
    // EPwm1Regs.TZCLR.bit.OST = 1;
    // EPwm1Regs.TZCLR.bit.INT = 1;
    // EDIS;
    
       // Acknowledge this interrupt to receive more interrupts from group 2
       PieCtrlRegs.PIEACK.all = PIEACK_GROUP2;
    }
    
    void InitEPwm1Example()
    {
       EALLOW;
       EPwm1Regs.TBPRD = 6000;                         // Set timer period
       EPwm1Regs.TBPHS.half.TBPHS = 0x0000;            // Phase is 0
       EPwm1Regs.TBCTR = 0x0000;
    
       // Setup TBCLK
       EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up/down
       EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // Disable phase loading
       EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV4;       // Clock ratio to SYSCLKOUT
       EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV4;
    
       EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;    // Load registers every ZERO
       EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
       EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
       EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
       // Setup compare
       EPwm1Regs.CMPA.half.CMPA = 3000;
    
       // Set actions
       EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;             // Set PWM1A on CAU
       EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;			  // Clear PWM1A on CAD
    
       EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR;           // Clear PWM1B on CAU
       EPwm1Regs.AQCTLB.bit.CAD = AQ_SET;             // Set PWM1B on CAD
    
       // Define an event (DCAEVT1) based on TZ1 and TZ2
       EPwm1Regs.DCTRIPSEL.bit.DCAHCOMPSEL = DC_COMP1OUT;        // DCAH = Comparator 1 output
       EPwm1Regs.DCTRIPSEL.bit.DCALCOMPSEL = DC_TZ2;             // DCAL = TZ2
       EPwm1Regs.TZDCSEL.bit.DCAEVT1 = TZ_DCAH_LOW;              // DCAEVT1 =  DCAH low(will become active as Comparator output goes low)
       EPwm1Regs.DCACTL.bit.EVT1SRCSEL = DC_EVT1;                // DCAEVT1 = DCAEVT1 (not filtered)
       EPwm1Regs.DCACTL.bit.EVT1FRCSYNCSEL = DC_EVT_ASYNC;       // Take async path
    
       // Define an event (DCBEVT1) based on TZ1 and TZ2
       EPwm1Regs.DCTRIPSEL.bit.DCBHCOMPSEL = DC_COMP1OUT;        // DCBH = Comparator 1 output
       EPwm1Regs.DCTRIPSEL.bit.DCBLCOMPSEL = DC_TZ2;             // DCAL = TZ2
       EPwm1Regs.TZDCSEL.bit.DCBEVT1 = TZ_DCBH_LOW;              // DCBEVT1 =  (will become active as Comparator output goes low)
       EPwm1Regs.DCBCTL.bit.EVT1SRCSEL = DC_EVT1;                // DCBEVT1 = DCBEVT1 (not filtered)
       EPwm1Regs.DCBCTL.bit.EVT1FRCSYNCSEL = DC_EVT_ASYNC;       // Take async path
    
       // Enable DCAEVT1 and DCBEVT1 are one shot trip sources
       // Note: DCxEVT1 events can be defined as one-shot.
       //       DCxEVT2 events can be defined as cycle-by-cycle.
       EPwm1Regs.TZSEL.bit.DCAEVT1 = 1;
       EPwm1Regs.TZSEL.bit.DCBEVT1 = 1;
    
       // What do we want the DCAEVT1 and DCBEVT1 events to do?
       // DCAEVTx events can force EPWMxA
       // DCBEVTx events can force EPWMxB
       EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_HI;           // EPWM1A will go high
       EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_LO;           // EPWM1B will go low
    
       // Enable TZ interrupt
       EPwm1Regs.TZEINT.bit.OST = 1;
       EDIS;
    }
    
    //===========================================================================
    // No more.
    //===========================================================================