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.

CCS/LAUNCHXL-F280049C: f280049C: ADC with Trip zone

Part Number: LAUNCHXL-F280049C
Other Parts Discussed in Thread: C2000WARE

Tool/software: Code Composer Studio

Hi Ti Community,

i am new in c2000 and i would be very grateful if anyone could help me, this is about turning off  ePWMs through Trip zone. i was dependent on an example of Trip zone but i don't know exactly how to connect the Trip zone to my Adcresult, so i get turning off all ePWMs when ADC = 0 Volt.

Regards

__interrupt void epwm1TZISR(void)
{
epwm1TZIntCount++;
// Toggle GPIO to notify when TZ is entered
GPIO_togglePin(25);
// Clear the flags - we will continue to take this interrupt until the TZ
// pin goes high.
EPWM_clearTripZoneFlag(EPWM1_BASE, (EPWM_TZ_INTERRUPT | EPWM_TZ_FLAG_CBC));

Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP2);

}

void initADC(void)
{
ADC_setVREF(ADCA_BASE, ADC_REFERENCE_INTERNAL, ADC_REFERENCE_3_3V);
ADC_setPrescaler(ADCA_BASE, ADC_CLK_DIV_4_0); 
ADC_setInterruptPulseMode(ADCA_BASE, ADC_PULSE_END_OF_CONV);
ADC_enableConverter(ADCA_BASE);
DEVICE_DELAY_US(1000);
}
void initEPWM(void)
{
EPWM_disableADCTrigger(EPWM8_BASE, EPWM_SOC_A);
EPWM_setADCTriggerSource(EPWM8_BASE, EPWM_SOC_A, EPWM_SOC_TBCTR_U_CMPA);
EPWM_setADCTriggerEventPrescale(EPWM8_BASE, EPWM_SOC_A, 1);
EPWM_setCounterCompareValue(EPWM8_BASE, EPWM_COUNTER_COMPARE_A, 83);
EPWM_setTimeBasePeriod(EPWM8_BASE, 166); // Frequenz der PWM8 600Khz
EPWM_setTimeBaseCounterMode(EPWM8_BASE, EPWM_COUNTER_MODE_STOP_FREEZE);
}

void initADCSOC(void)
{
ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER6, ADC_TRIGGER_EPWM8_SOCA, ADC_CH_ADCIN0, 10);

ADC_setInterruptSource(ADCA_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER6);

ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);

}

__interrupt void adcA1ISR(void)
{
Ud1 = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER6); 
if (Ud1<819)
{

EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_STOP_FREEZE);

}
else
{

EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP_DOWN);

dutyCycle =(Ud1*EPWM_TIMER_TBPRD/4095); 
EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_A, dutyCycle); 
EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_B, (EPWM_TIMER_TBPRD-dutyCycle)); 

}

ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}

void initEPWM1_Configuration(void)
{
// Enable TZ1 as one cycle-by-cycle trip sources
EPWM_enableTripZoneSignals(EPWM1_BASE, EPWM_TZ_SIGNAL_CBC1);
// Action on TZ1
EPWM_setTripZoneAction(EPWM1_BASE,
EPWM_TZ_ACTION_EVENT_TZA,
EPWM_TZ_ACTION_LOW);
// Enable TZ interrupt
EPWM_enableTripZoneInterrupt(EPWM1_BASE,
EPWM_TZ_INTERRUPT_CBC);
EPWM_setClockPrescaler(EPWM1_BASE,
EPWM_CLOCK_DIVIDER_1,
EPWM_HSCLOCK_DIVIDER_1);
EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP_DOWN);
EPWM_setTimeBaseCounter(EPWM1_BASE, 0);
EPWM_setTimeBasePeriod(EPWM1_BASE, EPWM_TIMER_TBPRD);
EPWM_setPeriodLoadMode(EPWM1_BASE, EPWM_PERIOD_SHADOW_LOAD);
EPWM_setCounterCompareShadowLoadMode(EPWM1_BASE,
EPWM_COUNTER_COMPARE_A,
EPWM_COMP_LOAD_ON_CNTR_ZERO);
EPWM_setCounterCompareShadowLoadMode(EPWM1_BASE,
EPWM_COUNTER_COMPARE_B,
EPWM_COMP_LOAD_ON_CNTR_ZERO);
EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_A, 0);
EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_B, 0);
// Dead-Band for ePWM1A/B
EPWM_setRisingEdgeDeadBandDelayInput(EPWM1_BASE,EPWM_DB_INPUT_EPWMA);
EPWM_setFallingEdgeDeadBandDelayInput(EPWM1_BASE,EPWM_DB_INPUT_EPWMA);
EPWM_setDeadBandDelayPolarity(EPWM1_BASE,EPWM_DB_RED,EPWM_DB_POLARITY_ACTIVE_HIGH);
EPWM_setDeadBandDelayPolarity(EPWM1_BASE, EPWM_DB_FED, EPWM_DB_POLARITY_ACTIVE_HIGH);
EPWM_setDeadBandDelayMode(EPWM1_BASE,EPWM_DB_RED,true);
EPWM_setDeadBandDelayMode(EPWM1_BASE, EPWM_DB_FED,true );
EPWM_setDeadBandOutputSwapMode(EPWM1_BASE,EPWM_DB_OUTPUT_A, false);
EPWM_setDeadBandOutputSwapMode(EPWM1_BASE, EPWM_DB_OUTPUT_B, false);
EPWM_setRisingEdgeDelayCount(EPWM1_BASE, Dead_Band_RED);
EPWM_setFallingEdgeDelayCount(EPWM1_BASE, Dead_Band_FED);

EPWM_setActionQualifierAction(EPWM1_BASE,
EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_HIGH,
EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(EPWM1_BASE,
EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_LOW,
EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
EPWM_setActionQualifierAction(EPWM1_BASE,
EPWM_AQ_OUTPUT_B,
EPWM_AQ_OUTPUT_HIGH,
EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(EPWM1_BASE,
EPWM_AQ_OUTPUT_B,
EPWM_AQ_OUTPUT_LOW,
EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
EPWM_setSyncOutPulseMode(EPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_COUNTER_ZERO); 
}

  • How are you detecting ADC = 0? Are you just reading the results and doing the comparison in software? There are a few ways you can do this in hardware that you may want to consider. The ADC has a post-processing block (PPB) that you can use to detect the crossing of a threshold and then send a signal out on the XBAR that could be routed to the PWM trip input.

    The CMPSS can be used to do something similar as well. There's a cmpss_ex1_asynch example that demonstrates it in

    C2000Ware_x_xx_xx_xx\driverlib\f28004x\examples\cmpss\

    Even if you decide you want to use PPB instead of CMPSS, the example should be helpful in figuring out how to configure the XBAR and the PWM trip signals.

    Whitney

  • Hi Whitney,

    yes exactly right i get ADC values with reading. i once read the CMPSS code but i didn't understand it exactly and how can i modify this program in my case ?

    Regards

  • Hi Whitney,

    i followed your hints, in my code i used the functions of ADC PPB and Trip zone, but my ePWM1 doesn't turn off at Adcresult=0Volt 

    //main
    void main(void)
    {
    epwm1TZIntCount = 0U;
    Interrupt_register(INT_EPWM1_TZ, &epwm1TZISR);
    initTZGPIO();
    Device_init();
    Device_initGPIO();
    Interrupt_enable(INT_EPWM1_TZ);
    Interrupt_initModule();
    Interrupt_initVectorTable();
    Interrupt_register(INT_ADCA1, &adcA1ISR);
    initEPWMGPIO();
    initEPWM1_Configuration();
    SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    initADC();
    initEPWM();
    initADCSOC();
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    Interrupt_enable(INT_ADCA1);

    EINT;
    ERTM;

    while(1)
    {
    EPWM_enableADCTrigger(EPWM8_BASE, EPWM_SOC_A);
    EPWM_setTimeBaseCounterMode(EPWM8_BASE, EPWM_COUNTER_MODE_UP);
    EPWM_disableADCTrigger(EPWM8_BASE, EPWM_SOC_A);
    EPWM_setTimeBaseCounterMode(EPWM8_BASE, EPWM_COUNTER_MODE_STOP_FREEZE);
    }
    }

    __interrupt void epwm1TZISR(void)
    {
    epwm1TZIntCount++;
    // Toggle GPIO to notify when TZ is entered
    GPIO_togglePin(25);
    // Clear the flags - we will continue to take this interrupt until the TZ
    // pin goes high.
    EPWM_clearTripZoneFlag(EPWM1_BASE, (EPWM_TZ_INTERRUPT | EPWM_TZ_FLAG_CBC));
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP2);
    }

    void initADC(void)
    {
    ADC_setupPPB(ADCA_BASE, ADC_PPB_NUMBER1, ADC_SOC_NUMBER6);
    ADC_enablePPBEvent(ADCA_BASE, ADC_PPB_NUMBER1, ADC_EVT_TRIPLO);
    ADC_setPPBReferenceOffset(ADCA_BASE, ADC_PPB_NUMBER1 , 0);
    ADC_setPPBTripLimits(ADCA_BASE, ADC_PPB_NUMBER1, 4095, 819);
    ADC_setVREF(ADCA_BASE, ADC_REFERENCE_INTERNAL, ADC_REFERENCE_3_3V); 
    ADC_setPrescaler(ADCA_BASE, ADC_CLK_DIV_4_0);
    ADC_setInterruptPulseMode(ADCA_BASE, ADC_PULSE_END_OF_CONV);
    ADC_enableConverter(ADCA_BASE);
    DEVICE_DELAY_US(1000);
    }
    void initEPWM(void)
    {
    EPWM_disableADCTrigger(EPWM8_BASE, EPWM_SOC_A);
    EPWM_setADCTriggerSource(EPWM8_BASE, EPWM_SOC_A, EPWM_SOC_TBCTR_U_CMPA);
    EPWM_setADCTriggerEventPrescale(EPWM8_BASE, EPWM_SOC_A, 1);
    EPWM_setCounterCompareValue(EPWM8_BASE, EPWM_COUNTER_COMPARE_A, 83);
    EPWM_setTimeBasePeriod(EPWM8_BASE, 166); // Frequenz der PWM8 600Khz
    EPWM_setTimeBaseCounterMode(EPWM8_BASE, EPWM_COUNTER_MODE_STOP_FREEZE);

    }
    void initADCSOC(void)
    {
    ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER6, ADC_TRIGGER_EPWM8_SOCA,
    ADC_CH_ADCIN6, 10);

    ADC_setInterruptSource(ADCA_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER6);
    ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER1);
    ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);

    }
    __interrupt void adcA1ISR(void)
    {
    Ud1 = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER6); 

    dutyCycle =(Ud1*EPWM_TIMER_TBPRD/4095); 
    EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_A, dutyCycle); 
    EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_B, (EPWM_TIMER_TBPRD-dutyCycle)); 
    ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
    }
    void initEPWM1_Configuration(void) 
    {
    // Enable TZ1 as one cycle-by-cycle trip sources
    EPWM_enableTripZoneSignals(EPWM1_BASE, EPWM_TZ_SIGNAL_CBC1);
    // Action on TZ1
    EPWM_setTripZoneAction(EPWM1_BASE,
    EPWM_TZ_ACTION_EVENT_TZA,
    EPWM_TZ_ACTION_HIGH);
    // Enable TZ interrupt
    EPWM_enableTripZoneInterrupt(EPWM1_BASE,
    EPWM_TZ_INTERRUPT_CBC);
    XBAR_setEPWMMuxConfig(XBAR_TRIP4, XBAR_EPWM_MUX00_ADCAEVT1);
    XBAR_enableEPWMMux(XBAR_TRIP4, XBAR_MUX00);
    EPWM_setClockPrescaler(EPWM1_BASE,
    EPWM_CLOCK_DIVIDER_1,
    EPWM_HSCLOCK_DIVIDER_1);
    EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP_DOWN);
    EPWM_setTimeBaseCounter(EPWM1_BASE, 0);
    EPWM_setTimeBasePeriod(EPWM1_BASE, EPWM_TIMER_TBPRD);
    EPWM_setPeriodLoadMode(EPWM1_BASE, EPWM_PERIOD_SHADOW_LOAD);
    EPWM_setCounterCompareShadowLoadMode(EPWM1_BASE,
    EPWM_COUNTER_COMPARE_A,
    EPWM_COMP_LOAD_ON_CNTR_ZERO);
    EPWM_setCounterCompareShadowLoadMode(EPWM1_BASE,
    EPWM_COUNTER_COMPARE_B,
    EPWM_COMP_LOAD_ON_CNTR_ZERO);
    EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_A, 0);
    EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_B, 0);
    // Dead-Band for ePWM1A/B
    EPWM_setRisingEdgeDeadBandDelayInput(EPWM1_BASE,EPWM_DB_INPUT_EPWMA);
    EPWM_setFallingEdgeDeadBandDelayInput(EPWM1_BASE,EPWM_DB_INPUT_EPWMA);
    EPWM_setDeadBandDelayPolarity(EPWM1_BASE,EPWM_DB_RED,EPWM_DB_POLARITY_ACTIVE_HIGH);
    EPWM_setDeadBandDelayPolarity(EPWM1_BASE, EPWM_DB_FED, EPWM_DB_POLARITY_ACTIVE_LOW);
    EPWM_setDeadBandDelayMode(EPWM1_BASE,EPWM_DB_RED,true);
    EPWM_setDeadBandDelayMode(EPWM1_BASE, EPWM_DB_FED,true );
    EPWM_setDeadBandOutputSwapMode(EPWM1_BASE,EPWM_DB_OUTPUT_A, false);
    EPWM_setDeadBandOutputSwapMode(EPWM1_BASE, EPWM_DB_OUTPUT_B, false);
    EPWM_setRisingEdgeDelayCount(EPWM1_BASE, Dead_Band_RED);
    EPWM_setFallingEdgeDelayCount(EPWM1_BASE, Dead_Band_FED);

    EPWM_setActionQualifierAction(EPWM1_BASE,
    EPWM_AQ_OUTPUT_A,
    EPWM_AQ_OUTPUT_HIGH,
    EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
    EPWM_setActionQualifierAction(EPWM1_BASE,
    EPWM_AQ_OUTPUT_A,
    EPWM_AQ_OUTPUT_LOW,
    EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    EPWM_setActionQualifierAction(EPWM1_BASE,
    EPWM_AQ_OUTPUT_B,
    EPWM_AQ_OUTPUT_LOW,
    EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
    EPWM_setActionQualifierAction(EPWM1_BASE,
    EPWM_AQ_OUTPUT_B,
    EPWM_AQ_OUTPUT_HIGH,
    EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    EPWM_setSyncOutPulseMode(EPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_COUNTER_ZERO); //Synchronize pulse when counting to zero
    }
    void initEPWMGPIO(void)
    {
    GPIO_setPadConfig(0, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(GPIO_0_EPWM1A);
    GPIO_setPadConfig(1, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(GPIO_1_EPWM1B);
    }
    void initTZGPIO(void)
    {
    /* // Set GPIO 58 as as Asynchronous input with pull up enabled
    GPIO_setPadConfig(58, GPIO_PIN_TYPE_PULLUP);
    GPIO_setPinConfig(GPIO_58_GPIO58);
    GPIO_setDirectionMode(58, GPIO_DIR_MODE_IN);
    GPIO_setQualificationMode(58, GPIO_QUAL_ASYNC);
    // Set GPIO 58 as TZ1 input
    XBAR_setInputPin(XBAR_INPUT1, 58);*/
    // Configure GPIO 25 as general purpose GPIO for monitoring when the TZ
    // Interrupt has been entered
    GPIO_setPadConfig(25, GPIO_PIN_TYPE_STD);
    GPIO_setPinConfig(GPIO_25_GPIO25);
    GPIO_setDirectionMode(25, GPIO_DIR_MODE_OUT);
    }

  • Move your call to Interrupt_register() below the call to Interrupt_initVectorTable(). initVectorTable() writes a default entry to all the vectors, so it'll just overwrite what Interrupt_register does. The fact that you didn't see any issues from this seems to confirm that the trip isn't working though...

    Can you compare your configuration of the EPWM to that in cmpss_ex1_asynch? I think the XBAR trip signals come through the digital compare module in the EPWM (see the block diagrams in the EPWM chapter of the device technical reference manual).

    Whitney

  • "Can you compare your configuration of the EPWM to that in cmpss_ex1_asynch? I think the XBAR trip signals come through the digital compare module in the EPWM"

    exactly this setting i don't quite understand, the program of cmpss and how i can connect the X-Bar signals to the digital compare, can you please help to do that ?

    Regards

  • I think your XBAR configuration looks good. You have the ADCEVT1 signal going to TRIP4. Now you just need to get TRIP4 connected to TZA in the trip zone subsystem.

    Again, I think looking at the block diagram of the Digital Compare subsystem will help you find the path. The CMPSS example

    • Routes TRIP4 through the trip combination input through DCBH (see EPWM_enableDigitalCompareTripCombinationInput())
    • Configures DCBEVT1 to occur when DCBH is high (see EPWM_setTripZoneDigitalCompareEventCondition())
    • Leaves DCBEVT1 unfiltered and asynchronous (see EPWM_setDigitalCompareEventSource())
    • Allows the DCBEVT1 to trip the PWM (see EPWM_enableTripZoneSignals())

    So in your case, it looks like you want CBC on channel A, you'll want to send TRIP4 through DCAEVT2. See if you can use the functions above that were used  in the CMPSS example and adjust their parameters appropriately.

    Whitney