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: Action Qualifier Clear Lo on T1

Part Number: TMS320F280049C

Hi,

I am using T1 in the Action Qualifier Submodule to clear EPWM1A Lo, but it looks like the output is instead going high impedance. Perhaps there is some configuration I am overlooking?

Background/Setup:

I originally was trying to verify ADC conversion time. The signal measured by the ADC is the output of DACA, which is initially set to a low value. Using the PPB, if the measurement is too high, TRIPHI causes an event which is identified by the Digital Comparator. This causes a T1 event which is configured to drive the EPWM1A Lo. 

EPWM1A is configured to 5us period at 80% duty. Time Base is up count. EPWM1A is Set Hi on TBCTR = 0, and Cleared Lo on CMPA.

To do the test, initially DACA is below the PPB TRIPHI threshold and EPWM1A is running. Using the watch window, DACA is set above the trip level. SOC0 is started on the next rising PWM edge. Once the conversion is complete, EPWM1A Lo will be terminated.

Results:

I have attached an image of the waveform. Yellow is the PWM and Pink is the DACA.

If I use the Action Qualifier Submodule T1, I get the "high impedance" looking result.

If I use CBC Trip Zone, the test works.

Code:

void main(void)
{
    //////////////////////////////////
    ///// Generic Initialization /////
    //////////////////////////////////

    // Initialize device clock and peripherals
    InitSysCtrl();

    // Initialize GPIO and configure the GPIO pin as a push-pull output
    InitGpio();
    GPIO_SetupPinMux(DEVICE_GPIO_PIN_LED1, GPIO_MUX_CPU1, 0);
    GPIO_SetupPinOptions(DEVICE_GPIO_PIN_LED1, GPIO_OUTPUT, GPIO_PUSHPULL);

    GPIO_SetupPinMux(DEVICE_GPIO_PIN_LED2, GPIO_MUX_CPU1, 0);
    GPIO_SetupPinOptions(DEVICE_GPIO_PIN_LED2, GPIO_OUTPUT, GPIO_PUSHPULL);

    GpioDataRegs.GPASET.bit.GPIO31 = 1;     // left LED
    GpioDataRegs.GPBSET.bit.GPIO34 = 1;     // Right LED


    //////////////////////////////////
    ///// Generic Interrupt Init /////
    //////////////////////////////////

    // Initialize PIE and clear PIE registers. Disables CPU interrupts. 
    DINT;
    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).
    InitPieVectTable();

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

    //CMPSS_investigation();
    ADC_investigation();

    // Loop Forever
    for(;;)
    {

        DacaRegs.DACVALS.all = iSNS; // update in watch window as needed
        ADC_test();


    }
}


void ADC_investigation(void)
{
    /* Plan
     * - EPWM1A is configured for 5us period. Configure 80% duty. HI on ZRO, LOW on CMPA = 4000.
     * - DACA is turned on for measurement by A0 (SOC0)
     * - SOC0 starts with EPWM1A zero. To facilitate testing, SOC0 will be dis/enabled in the debug window as needed
     * 1. PPB to check limit hi, limit lo, verify measurement result [DONE]
     * 2. Use PPB to terminate EPWM1A. Should provide conversion timing measurement. 
     */

    ///////////////////////////////////////////////
    /////           Initial Setup           ///////
    ///////////////////////////////////////////////

    /////           EPWM1A           ///////
    GPIO_SetupPinMux(DEVICE_GPIO_PIN_EPWM1A, GPIO_MUX_CPU1, 1);
    EALLOW;
    //CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;              // 0 = SYSCLK/1, 1 = SYSCLK/2 (default)
    EPwm1Regs.TBCTL.bit.FREE_SOFT = 2;              // run during debug mode halts
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;      // count up (arbitrary for this)
    EPwm1Regs.TBPRD = 500;                          // Period = 500 counts @ 100MHz = 5us
    EPwm1Regs.CMPA.bit.CMPA = 400;                  // Will use CMPA to set PWM LO @ 80% Duty Fixed
    EPwm1Regs.AQCTLA.bit.ZRO = 2;                   // Set HI every period
    EPwm1Regs.AQCTLA.bit.CAU = 1;                   // Set LO every CMPA
    EPwm1Regs.ETSEL.bit.SOCASEL = 1;                // 1 = SOCA on ZRO
    EPwm1Regs.ETPS.bit.SOCAPRD = 1;                 // 1 = generate SOCA on first event
    EPwm1Regs.ETSEL.bit.SOCAEN = 1;                 // 1 = Enable SOCA Trigger on ZRO
    EDIS;

    /////           DACA           ///////
    EALLOW;
    AnalogSubsysRegs.ANAREFCTL.bit.ANAREFASEL = 0;      // 0 = internal, 1 = external (default)
    AnalogSubsysRegs.ANAREFCTL.bit.ANAREFA2P5SEL = 0;   // 0 = 1.65V (default), 1 = 2.5V
    DacaRegs.DACCTL.bit.LOADMODE = 0;                   // 0 = update DAC on sysclk (default), 1 = EPWMSYNCO
    DacaRegs.DACCTL.bit.DACREFSEL = 1;                  // 0 = Reference: VDAC (external, default), 1 = ADC reference (set above)
    DacaRegs.DACCTL.bit.MODE = 1;                       // 0 = Gain x1 (default), 1 = Gain x2
    DacaRegs.DACOUTEN.bit.DACOUTEN = 1;
    DELAY_US(5000);                                     // max power up time per datasheet is 5000us
    DacaRegs.DACVALS.all = iSNS;                        // halfway point of 2^12 (1.65/2 = 0.825V, 2.5/2 = 1.25V)
    EDIS;

    /////           ADC           ///////
    EALLOW;
    // Use ADC to measure DAC (DACA and A0 are same pin, so use A0)
    // Internal Vref already setup setup; VrefA is shared between ADCA and DACA
    // AnalogSubsysRegs.ANAREFCTL.bit.ANAREFASEL = 0;      // 0 = internal, 1 = external (default)
    // AnalogSubsysRegs.ANAREFCTL.bit.ANAREFA2P5SEL = 0;   // 0 = 1.65V (default), 1 = 2.5V

    // Setup A0 as SOC0
    AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0;                  // SOC0 will convert A0 (DACA_OUT)
    AdcaRegs.ADCSOC0CTL.bit.ACQPS = 9;                  // 9+1=10, Minimum window is 75 ns SYSCLK cycles (arbitrary at this point)
    AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5;                // Trigger by ePWM1, ADCSOCA
    AdcaRegs.ADCCTL2.bit.PRESCALE = 2;                  // 2 = divide SYSCLK by 2; need to prescale 100MHZ SYSCLK to 50MHZ max.
    AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;                  // turn on ADCA module
    EDIS;
    DELAY_US(1000);                                     // delay allowing for ADC power up time

    ///////////////////////////////////////////////
    ///// 1. PPB to check limit hi, limit lo  /////
    ///////////////////////////////////////////////

    EALLOW;
    AdcaRegs.ADCPPB4CONFIG.bit.CBCEN = 1;           // 1 = Enable CBC, 0 = disabled (default)
    AdcaRegs.ADCPPB4CONFIG.bit.CONFIG = 0;          // 0 (default) = PPB1 is linked to SOC0
    AdcaRegs.ADCPPB4TRIPHI.bit.LIMITHI = limit_HI;
    AdcaRegs.ADCPPB4TRIPLO.bit.LIMITLO = limit_LO;
    AdcaRegs.ADCEVTSEL.bit.PPB4TRIPHI = 1;              // Enable PPB1 Trip HI to PWM
    AdcaRegs.ADCEVTSEL.bit.PPB4TRIPLO = 1;              // Enable PPB1 TRIP LO to PWM
    AdcaRegs.ADCPPB4OFFCAL.all = 0x200;      // 0x200 = +512
    //AdcaRegs.ADCPPB4OFFREF = 500;           // subtract 500
    AdcaRegs.ADCEVTCLR.all = 0xFFFF;        // Clear any pending flags
    EDIS;

    ///////////////////////////////////////////////
    //////  2. Use PPB to terminate EPWM1A  ///////
    ///////////////////////////////////////////////

    /* Setup ePWM XBAR and Digital Comparator.
     * Input to XBAR comes from ADCA EVENT4, output is TRIP4 which is fed to Digital Comparator.
     * DCAEVT2 is used to terminate EPWM1A.     */

    EALLOW;
    EPwmXbarRegs.TRIP4MUX0TO15CFG.bit.MUX6 = 2; // Select input 6 of XBAR TRIP MUX to be ADCAEVT4 (PPB4)
    EPwmXbarRegs.TRIP4MUXENABLE.bit.MUX6 = 1;   // Enable input 6 to trigger Trip 4

    EPwm1Regs.DCTRIPSEL.bit.DCAHCOMPSEL = 3;    // TRIPIN4 on digital comparator +in
    EPwm1Regs.DCTRIPSEL.bit.DCALCOMPSEL = 3;    // TRIPIN4 on digital comparator -in (not needed)
    EPwm1Regs.TZDCSEL.bit.DCAEVT2 = 2;          // digital comparator DCAEVT2 high on DCAH assertion (TRIP4 high).

    // These new registers are active by default, disable them.
    EPwm1Regs.TZCTLDCA.all = 0xFFFF;
    EPwm1Regs.TZCTLDCB.all = 0xFFFF;

    // force low on AQ T1, this code doesn't work
    EPwm1Regs.AQTSRCSEL.bit.T1SEL = 1;  // 1 = T1 trips on DCAEVT2
    EPwm1Regs.AQCTLA2.bit.T1U = 1;      // 1 = force LO on T1
    
    // force low on Trip Zone, this code works
    //EPwm1Regs.TZCTL.bit.DCAEVT2 = 2;    

    EDIS;

}

void ADC_test(void)
{

    if (AdcaRegs.ADCEVTSTAT.bit.PPB4TRIPHI == 1)
    {
        GpioDataRegs.GPACLEAR.bit.GPIO31 = 1;     // left LED
        GpioDataRegs.GPBSET.bit.GPIO34 = 1;     // Right LED
        //AdcaRegs.ADCEVTCLR.bit.PPB4TRIPHI = 1;

    }

    else if (AdcaRegs.ADCEVTSTAT.bit.PPB4TRIPLO == 1)
    {
        GpioDataRegs.GPASET.bit.GPIO31 = 1;     // Left LED
        GpioDataRegs.GPBCLEAR.bit.GPIO34 = 1;     // Right LED
        //AdcaRegs.ADCEVTCLR.bit.PPB4TRIPLO = 1;
    }

    else
    {
        GpioDataRegs.GPASET.bit.GPIO31 = 1;     // left LED
        GpioDataRegs.GPBSET.bit.GPIO34 = 1;     // Right LED
    }
}

  • Hi,

    The high impedance seems to be due to trip zone action, and not due to T1 action in the action qualifier settings.
    I see that you are configuring TZCTLDCA/TZCTLDCB registers.
    Have you enabled the registers via TZCTL2[ETZE] bit?
    Please refer to Table 15-59. TZCTL2 Register Field Descriptions
  • Thank you Subrahmanya. Yes, you were correct! I had not configured DCAEVT2 bit in the TZCTL register; the default value is 00 high impedance, when I changed to 11 do nothing, it works. Additionally I learned TZCTLDCA and TZCTLDBC do not need to be configured since I don't use TZCTL2. Lines 148-154 become:

        // Don't need to configure these, since not using TZCTL2
        //EPwm1Regs.TZCTLDCA.all = 0xFFFF;
        //EPwm1Regs.TZCTLDCB.all = 0xFFFF;
        
        EPwm1Regs.TZCTL.bit.DCAEVT2 = 3;    // 0 (default) = high impedance, 3 = do nothing. Deconflict with T1 below.
        EPwm1Regs.AQTSRCSEL.bit.T1SEL = 1;  // 1 = T1 trips on DCAEVT2
        EPwm1Regs.AQCTLA2.bit.T1U = 1;      // 1 = force LO on T1


  • Good to know your issue is resolved. Yes - you do not need to use TZCTLDCA and TZCTLDBC.
  • If you look in my original post, The second picture shows a PWM pulse of 390ns. This was an attempt to measure the ADC conversion time, by setting SOC to start of ePWM and, and then terminating ePWM using the ADC PPB.

    Can you please confirm this method is giving a reasonable assessment of conversion time?

    The time should have been 10 SYSCLK for S&H, plus 23 SYSCLK for conversion = 330ns. 6 SYSCLK are being inserted somewhere, I am assuming there are a handful of SYSCLKs for synchronization/moving data along the way.
  • Hi, There could be some delay from the time ADC result is available to the PPB event causing trip Action on the PWM output. If you have to know the exact ADC conversion time, this data should be available in the data sheet. Also, I suggest that you create separate post if you run into any issues with ADC/ conversion time measurements etc. so the ADC experts can address your questions.

    -Bharathi