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.

TMS320F280049C: One shot tripzone with dead band is not latching

Part Number: TMS320F280049C

Hi

I have configured a comparator to detect a fault and output is passed to DCBH of epwm1 through epwmXBAR. If a trip occurs I want EPWM1A to go low and EPW1B to go high with some dead time, to implement this DCBEVT1 (enabled one-shot trigger) is set to trigger T1 in the action qualifier. Everything looks working, but PWM outputs are not getting latched after the occurrence of an event.

In the normal condition, EPWM1A is high and EPWM1B is low, when a fault occurs EPWM1A is low and EPWM1B is high for sometime later it comes back to its original state, I have attached an image of the PWM waveform for reference (EPWM1A - Yellow, EPWM1B - Blue). After the occurrence of an event TZFLG.DCBEVT1, TZFLG.OST and TZOSTFLG.DCBEVT1 is set to 1 but I don't understand why PWMs are not getting latched after an event. 

I have also attached the code for reference, please let me know if I missed any settings.

//#############################################################################
//
// FILE:   cmpss_ex2_digital_filter.c
//
// TITLE:  CMPSS Digital Filter Configuration
//
//! \addtogroup driver_example_list
//! <h1> CMPSS Digital Filter Configuration </h1>
//!
//! This example enables the CMPSS1 COMPH comparator and feeds the output
//! through the digital filter to the GPIO14/OUTPUTXBAR3 pin.
//!
//! \b External \b Connections \n
//!  - Output can be observed on GPIO14
//!
//! \b Watch \b Variables \n
//!  - None
//!
//
//#############################################################################
// $TI Release: F28004x Support Library v1.06.00.00 $
// $Release Date: Fri May 24 03:33:32 CDT 2019 $
// $Copyright:
// Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without 
// modification, are permitted provided that the following conditions 
// are met:
// 
//   Redistributions of source code must retain the above copyright 
//   notice, this list of conditions and the following disclaimer.
// 
//   Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the 
//   documentation and/or other materials provided with the   
//   distribution.
// 
//   Neither the name of Texas Instruments Incorporated nor the names of
//   its contributors may be used to endorse or promote products derived
//   from this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################

//
// Included Files
//
#include "driverlib.h"
#include "device.h"

//
// Function Prototypes
//
void initCMPSS(void);
void initEPWM(void);

//
// Main
//

uint16_t status = 0;
void main(void)
{
    //
    // Initialize device clock and peripherals
    //
    Device_init();

    //
    // Disable pin locks and enable internal pullups.
    //
    Device_initGPIO();

    //
    // Initialize PIE and clear PIE registers. Disables CPU interrupts.
    //
    Interrupt_initModule();

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    Interrupt_initVectorTable();

    ASysCtl_selectCMPHPMux(ASYSCTL_CMPHPMUX_SELECT_7, 2);
    //
    // Set up COMP7H
    //
    initCMPSS();

    //
    // Set up ePWM1 to take CTRIPH as TRIP4 for its DC trip input
    //
    initEPWM();

    //
    // Configure GPIO11 to output CTRIPOUT1H (routed through XBAROUTPUT7)
    //
    GPIO_setPinConfig(GPIO_11_OUTPUTXBAR7);
    GPIO_setPinConfig(GPIO_0_EPWM1A);
    GPIO_setPinConfig(GPIO_1_EPWM1B);

    //
    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    //
    EINT;
    ERTM;

    //
    // Loop indefinitely
    //
    while (1)
    {
        status = CMPSS_getStatus(CMPSS7_BASE);

    }
}

//
// initCMPSS - Function to configure the high comparator of CMPSS1
//
void initCMPSS(void)
{
    //
    // Enable CMPSS and configure the negative input signal to come from
    // the DAC
    //
    //UV
    CMPSS_enableModule(CMPSS7_BASE);
    CMPSS_configHighComparator(CMPSS7_BASE, CMPSS_INSRC_DAC);
    //

    //
    // Use VDDA as the reference for the DAC and set DAC value to midpoint for
    // arbitrary reference
    // UV
    CMPSS_configDAC(CMPSS7_BASE, CMPSS_DACREF_VDDA | CMPSS_DACVAL_SYSCLK |
    CMPSS_DACSRC_SHDW);
    CMPSS_setDACValueHigh(CMPSS7_BASE, 1092);

    //
    // Configure digital filter. For this example, the maxiumum values will be
    // used for the clock prescale, sample window size, and threshold.
    //
    CMPSS_configFilterHigh(CMPSS7_BASE, 0, 16, 15);

    //
    // Initialize the filter logic and start filtering
    //
    CMPSS_initFilterHigh(CMPSS7_BASE);

    CMPSS_clearFilterLatchHigh(CMPSS7_BASE);
    //
    // Configure the output signals. Both CTRIPH and CTRIPOUTH will be fed by
    // the filter output.
    CMPSS_configOutputsHigh(CMPSS7_BASE, CMPSS_TRIP_FILTER |
    CMPSS_TRIPOUT_FILTER);


    XBAR_setOutputMuxConfig(XBAR_OUTPUT7, XBAR_OUT_MUX12_CMPSS7_CTRIPOUTH);
    XBAR_enableOutputMux(XBAR_OUTPUT7, XBAR_MUX12);

}

//
// initEPWM - Function to configure ePWM8 and the ePWM X-BAR to take CTRIPH as
//            the DC trip input
//
void initEPWM(void)
{
    //
    // Disable the ePWM time base clock before configuring the module
    //
    SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

    //EPWM
    // setup the Time-Base Control Register (TBCTL)
    EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP_DOWN);
    EPWM_disablePhaseShiftLoad(EPWM1_BASE);
    EPWM_setPeriodLoadMode(EPWM1_BASE, EPWM_PERIOD_DIRECT_LOAD);
    EPWM_setSyncOutPulseMode(EPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_SOFTWARE);
    EPWM_setClockPrescaler(EPWM1_BASE, EPWM_CLOCK_DIVIDER_1,
                           EPWM_HSCLOCK_DIVIDER_1);
    EPWM_setCountModeAfterSync(EPWM1_BASE, EPWM_COUNT_MODE_UP_AFTER_SYNC);
    EPWM_setEmulationMode(EPWM1_BASE, EPWM_EMULATION_FREE_RUN);

    // setup the Timer-Based Phase Register (TBPHS)
    EPWM_setPhaseShift(EPWM1_BASE, 0);

    // setup the Time-Base Counter Register (TBCTR)
    EPWM_setTimeBaseCounter(EPWM1_BASE, 0);

    // setup the Time-Base Period Register (TBPRD)
    // set to zero initially
    EPWM_setTimeBasePeriod(EPWM1_BASE, 0);

    // setup the Counter-Compare Control Register (CMPCTL)
    EPWM_setCounterCompareShadowLoadMode(EPWM1_BASE, EPWM_COUNTER_COMPARE_A,
                                         EPWM_COMP_LOAD_ON_CNTR_ZERO);

    EPWM_disableCounterCompareShadowLoadMode(EPWM1_BASE,
                                             EPWM_COUNTER_COMPARE_B);

    //
    EPWM_disableCounterCompareShadowLoadMode(EPWM1_BASE,
                                             EPWM_COUNTER_COMPARE_C);

    //
    EPWM_disableCounterCompareShadowLoadMode(EPWM1_BASE,
                                             EPWM_COUNTER_COMPARE_D);

    // setup the Action-Qualifier Output A Register (AQCTLA)
    EPWM_setActionQualifierAction(EPWM1_BASE, EPWM_AQ_OUTPUT_A,
                                  EPWM_AQ_OUTPUT_HIGH,
                                  EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); // changed from High to low

    EPWM_setActionQualifierAction(EPWM1_BASE, EPWM_AQ_OUTPUT_A,
                                  EPWM_AQ_OUTPUT_LOW,
                                  EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA); // changed from low to high

    // setup the Action-qualifier Continuous Software Force Register
    // (AQCSFRC)
    EPWM_setActionQualifierContSWForceAction(EPWM1_BASE, EPWM_AQ_OUTPUT_B,
                                             EPWM_AQ_SW_OUTPUT_HIGH);

    // setup the Dead-Band Generator Control Register (DBCTL)
    EPWM_setDeadBandDelayMode(EPWM1_BASE, EPWM_DB_RED, true);
    EPWM_setDeadBandDelayMode(EPWM1_BASE, EPWM_DB_FED, true);

    // select EPWMA as the input to the dead band generator
    EPWM_setRisingEdgeDeadBandDelayInput(EPWM1_BASE,
    EPWM_DB_INPUT_EPWMA);

    // configure the right polarity for active high complementary config.
    EPWM_setDeadBandDelayPolarity(EPWM1_BASE, EPWM_DB_RED,
                                  EPWM_DB_POLARITY_ACTIVE_HIGH);
    EPWM_setDeadBandDelayPolarity(EPWM1_BASE, EPWM_DB_FED,
                                  EPWM_DB_POLARITY_ACTIVE_LOW);

    // setup the Dead-Band Rising Edge Delay Register (DBRED)
    EPWM_setRisingEdgeDelayCount(EPWM1_BASE, 100);

    // setup the Dead-Band Falling Edge Delay Register (DBFED)
    EPWM_setFallingEdgeDelayCount(EPWM1_BASE, 100);

    // setup the PWM-Chopper Control Register (PCCTL)
    EPWM_disableChopper(EPWM1_BASE);

/*
     // setup the Trip Zone Select Register (TZSEL)
     EPWM_disableTripZoneSignals(EPWM1_BASE,
     EPWM_TZ_SIGNAL_CBC1 |
     EPWM_TZ_SIGNAL_CBC2 |
     EPWM_TZ_SIGNAL_CBC3 |
     EPWM_TZ_SIGNAL_CBC4 |
     EPWM_TZ_SIGNAL_CBC5 |
     EPWM_TZ_SIGNAL_CBC6 |
     EPWM_TZ_SIGNAL_DCAEVT2 |
     EPWM_TZ_SIGNAL_DCBEVT2 |
     EPWM_TZ_SIGNAL_OSHT1 |
     EPWM_TZ_SIGNAL_OSHT2 |
     EPWM_TZ_SIGNAL_OSHT3 |
     EPWM_TZ_SIGNAL_OSHT4 |
     EPWM_TZ_SIGNAL_OSHT5 |
     EPWM_TZ_SIGNAL_OSHT6 |
     EPWM_TZ_SIGNAL_DCAEVT1 |
     EPWM_TZ_SIGNAL_DCBEVT1);
*/

    //

    EPWM_setActionQualifierT1TriggerSource(EPWM1_BASE,
                                           EPWM_AQ_TRIGGER_EVENT_TRIG_DCB_1);

    EPWM_setAdditionalActionQualifierActionComplete(EPWM1_BASE,
                                                    EPWM_AQ_OUTPUT_A,
                                                    EPWM_AQ_OUTPUT_LOW_UP_T1);

    EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_A, 0);

    //
    // Initializing dummy values for ePWM counter and period
    //
    //EPWM_setTimeBaseCounter(EPWM1_BASE, 0);
    EPWM_setTimeBasePeriod(EPWM1_BASE, 2500);
    //
    // Configure ePWM1A & B to do nothing on TZA & TZB TRIP
    //
    EPWM_setTripZoneAction(EPWM1_BASE,EPWM_TZ_ACTION_EVENT_TZB,
                           EPWM_TZ_ACTION_DISABLE);
    EPWM_setTripZoneAction(EPWM1_BASE,EPWM_TZ_ACTION_EVENT_TZA,
                               EPWM_TZ_ACTION_DISABLE);



    //
    // Trigger event when DCBH is high
    //
    EPWM_setTripZoneDigitalCompareEventCondition(EPWM1_BASE,
                                                 EPWM_TZ_DC_OUTPUT_B1,
                                                 EPWM_TZ_EVENT_DCXH_HIGH);

    //
    // Configure DCBH to use TRIP4 as an input
    //
    EPWM_enableDigitalCompareTripCombinationInput(EPWM1_BASE,
    EPWM_DC_COMBINATIONAL_TRIPIN4,
                                                  EPWM_DC_TYPE_DCBH);

    //
    // Enable DCB as OST
    //
    EPWM_enableTripZoneSignals(EPWM1_BASE, EPWM_TZ_SIGNAL_DCBEVT1);


    //
    // Configure the DCB path to be unfiltered and asynchronous
    //
    EPWM_setDigitalCompareEventSource(EPWM1_BASE, EPWM_DC_MODULE_B,
                                      EPWM_DC_EVENT_1,
                                      EPWM_DC_EVENT_SOURCE_ORIG_SIGNAL);

    //
    // Configure TRIP4 to be CTRIP1H using the ePWM X-BAR
    //
    XBAR_setEPWMMuxConfig(XBAR_TRIP4, XBAR_EPWM_MUX12_CMPSS7_CTRIPH);
    XBAR_enableEPWMMux(XBAR_TRIP4, XBAR_MUX12);

    //
    // Clear trip flags
    //
    EPWM_clearTripZoneFlag(EPWM1_BASE, EPWM_TZ_INTERRUPT |
    EPWM_TZ_FLAG_OST);

    //
    // Sync the ePWM time base clock
    //
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
}

  • Hello, a subject-matter expert has been assigned to this thread. You should expect a response within 24 hours. 

  • You're setting your ACTION to occur through the action qualifier module. You need to configure the OST action inside the trip zone to change your EPWM outputs. If you dont use the OSHT action and instead use the RAW DCxEVTy events to cause an action, when the condition is removed, the EPWM will resume normal operations.

    Nima

  • Hi Nima

    I am setting my ACTIONS in action qualifier to implement deadband which is not possible if actions are set inside the trip zone. 

    I have observed that even when the DCBEVT1 event (fault condition) is present continuously EPWM resumes back to normal operations after some time ( similar to the waveform I posted earlier) 

    In 18.6.3 Action-Qualifier Event Priority section of https://www.ti.com/lit/ug/sprui33d/sprui33d.pdf, it says events occurring later in time have higher priority, so I think initially when T1 triggers, the action is taken but later CAU and CAD is occurring and it overwrites the T1 and EPWM resumes to normal operation. How should we avoid that? We want the ePWMs to be latched once T1 on action qualifier is triggered. 

  • If you use the DCEVTs in the T1/T2 action qualifer, that is the case... If you want it to stay you need to use the OST TZ override action.

    The T1/T2 event will only occur, then it wont matter if the signal stay high or not... If you want the event to stick, you need to use the TZ module.

    Nima

  • If you want to use T1 event, then what you are seeing is expected behavior. Only in the TZ actions can you get the behavior that you want. Or you can try the CLB for custome logic or a SW solution.

  • Okay. I understand. 

    But we need a solution where we can trip the ePWMs with deadtime. Please let us know a way to do so. 

  • Well the solution to having Trips + deadband is T1/T2 actions. But like I said, they will not be in a one-shot manner. Once the event passes, the following ZERO/PRD, CMAU/D, CMBU/D will change the output of the EPWM.

    For you is you need the specific requirements you have mentioned, you either have to look at how your DCA/DCB signals are generated. or use the SW or the CLB customization.

    Nima