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.

TMS320F280049: Issue with CMPSS to realise peak current mode control

Part Number: TMS320F280049

I am having issues with the CMPSS block to implement peak current mode control for a bi-directional DC/DC Converter (refer to this link for a block diagram).

Requirements:
- Fixed duty cycle (PWM A) with maximum on-time. This is interrupted if the inductor current exceeds the peak value set by the DAC of the comparator. After each period this is reset.
- When in 'RUN' mode, PWM #1 will always have complementary outputs A and B.
- When not in 'RUN' mode, the state machine forces all outputs low.
- The CLA does the compensator calculations and updates the CMPSS DAC with Cmpss1Regs.DACLVALS.all = value;
- The inductor current is sampled at the switching frequency and in the ISR routine, the CMPSS flags are cleared.

The software shown below is a derivation from various examples from the TI Resource Explorer and the TI forum.

Analog Sub System Initialisation:
EALLOW;
//
// PGA1_IN (Peak current mode control comparator high input of Inductor #1)
//
AnalogSubsysRegs.CMPLPMXSEL.bit.CMP1LPMXSEL = 0b010; // CMPSS1 : CMP1_LP2 : IL_POS

CMPSS initialisation:
//
// Enable CMPSS and configure the negative input signal to come from
// the DAC and the positive signal to come from pin PGA1_IN
//
CMPSS_enableModule(CMPSS1_BASE);
CMPSS_configLowComparator(CMPSS1_BASE, CMPSS_INSRC_DAC);

//
// Use VDDA as the reference for the DAC and set DAC value to midpoint for
// arbitrary reference.
//
CMPSS_configDAC(CMPSS1_BASE, CMPSS_DACREF_VDDA | CMPSS_DACVAL_SYSCLK | CMPSS_DACSRC_SHDW);
CMPSS_setDACValueLow(CMPSS1_BASE, 2048U);

//
// Configure the output signals. Both CTRIPL and CTRIPOUTL will be filtered
//
CMPSS_configOutputsLow(CMPSS1_BASE, CMPSS_TRIP_FILTER | CMPSS_TRIPOUT_FILTER);

//
// Invert the output signal as per PCMC structure
//
XBAR_invertOutputSignal(XBAR_OUTPUT1, true);

//
// Setup the Output X-BAR to output CTRIPOUTL on OUTPUTXBAR1
//
XBAR_setOutputMuxConfig(XBAR_OUTPUT1, XBAR_OUT_MUX01_CMPSS1_CTRIPOUTL);
XBAR_enableOutputMux(XBAR_OUTPUT1, XBAR_MUX01);

PWM initialisation:
//
// Disable the ePWM time base clock before configuring the module
//
SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

//
// Set up EPWM1 to
// - run on a base clock of SYSCLK / 1
// - have a period of EPWM1_PERIOD
// - run in count up mode
//
EPWM_setClockPrescaler(EPWM1_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);
EPWM_setTimeBasePeriod(EPWM1_BASE, EPWM1_PERIOD);
EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP);
EPWM_setTimeBaseCounter(EPWM1_BASE, 0U);
EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_A, EPWM_DUTY_CYCLE_MAX);

//
// Enable SOC-A and set it to assert when the counter hits
// zero. It asserts on every event
//
EPWM_enableADCTrigger(EPWM1_BASE, EPWM_SOC_A);
EPWM_setADCTriggerSource(EPWM1_BASE, EPWM_SOC_A, EPWM_SOC_TBCTR_ZERO);
EPWM_setADCTriggerEventPrescale(EPWM1_BASE, EPWM_SOC_A, 1U);

//
// EPWM1 should toggle each time its counter hits zero
//
EPWM_setActionQualifierAction(EPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_TOGGLE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierAction(EPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_TOGGLE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);

//
// On compare A, when counting up, pull the EPWM A output low
// On compare A, when counting down, pull the EPWM A output high
//
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_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);

//
// On compare A, when counting up, pull the EPWM B output high
// On compare A, when counting down, pull the EPWM B output low
//
EPWM_setActionQualifierAction(EPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
EPWM_setActionQualifierAction(EPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);


EPWM_setPhaseShift(EPWM1_BASE, PWM1_PHASE_SHIFT); // Set Phase register to zero
EPWM_disablePhaseShiftLoad(EPWM1_BASE); // Mastermodule
EPWM_setCountModeAfterSync(EPWM1_BASE, EPWM_COUNT_MODE_DOWN_AFTER_SYNC);
EPWM_setPeriodLoadMode(EPWM1_BASE, EPWM_PERIOD_SHADOW_LOAD);
EPWM_setSyncOutPulseMode(EPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_COUNTER_ZERO);

EPWM_setCounterCompareShadowLoadMode(EPWM1_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD);
EPWM_setCounterCompareShadowLoadMode(EPWM1_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD);

EPWM_setRisingEdgeDeadBandDelayInput(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_setRisingEdgeDelayCount(EPWM1_BASE, EPWM_MIN_DBRED);
EPWM_setFallingEdgeDelayCount(EPWM1_BASE, EPWM_MIN_DBFED);

//
// Configure ePWM1A to output low on TZA TRIP
//
EPWM_setTripZoneAction(EPWM1_BASE, EPWM_TZ_ACTION_EVENT_TZA, EPWM_TZ_ACTION_LOW);
EPWM_setTripZoneAction(EPWM1_BASE, EPWM_TZ_ACTION_EVENT_TZB, EPWM_TZ_ACTION_LOW);
EPWM_setTripZoneAction(EPWM1_BASE, EPWM_TZ_ACTION_EVENT_DCAEVT1, EPWM_TZ_ACTION_HIGH);

//
// Trigger event when DCAL is high
//
EPWM_setTripZoneDigitalCompareEventCondition(EPWM1_BASE, EPWM_TZ_DC_OUTPUT_A1, EPWM_TZ_EVENT_DCXL_HIGH);

//
// Configure DCAL to use TRIP4 as an input
//
EPWM_enableDigitalCompareTripCombinationInput(EPWM1_BASE, EPWM_DC_COMBINATIONAL_TRIPIN4, EPWM_DC_TYPE_DCAL);

//
// Enable DCA as OST
//
EPWM_enableTripZoneSignals(EPWM1_BASE, EPWM_TZ_SIGNAL_DCAEVT1 | EPWM_TZ_SIGNAL_OSHT1);

//
// Configure the DCA path to be filtered and asynchronous
//
EPWM_setDigitalCompareEventSource(EPWM1_BASE, EPWM_DC_MODULE_A, EPWM_DC_EVENT_1, EPWM_DC_EVENT_SOURCE_FILT_SIGNAL);

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

// Configure TRIP4 to be CTRIP2H using the ePWM X-BAR
//
XBAR_setEPWMMuxConfig(XBAR_TRIP4, XBAR_EPWM_MUX01_CMPSS1_CTRIPL);
XBAR_enableEPWMMux(XBAR_TRIP4, XBAR_MUX01);

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

//
// EPWM 1 should run freely in emulation mode
//
EPWM_setEmulationMode(EPWM1_BASE, EPWM_EMULATION_FREE_RUN);

ADC interrupt:
//
// Clear the interrupt flag
//
ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);

//
// Check if overflow has occurred
//
if(true == ADC_getInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1))
{
ADC_clearInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1);
ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);
}

//
// Acknowledge the interrupt
//
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);

if (state == ST_RUN) {
//
// Clear trip flags
//
EPWM_clearTripZoneFlag(EPWM1_BASE, EPWM_TZ_INTERRUPT | EPWM_TZ_FLAG_DCAEVT1 | EPWM_TZ_FLAG_OST );
}


Questions:
(1) The above code regulates the voltage albeit having high inductor peak currents more than the set peak current limit. From the above code, why doesn't my DCAEVT1 have complementary outputs on PWM1 A and PWM1 B? The actual outputs are either on maximum duty cycle (and complementary) or both A and B off. What am I missing in the code to realise my requirements?
(2) Why is my CMPSS1_CTRIPL register always '1' during debugging? Shouldn't this be toggling during operation which is passed onto the PWM module to trip the switching cycle?

  • Frank Ankapong (3736438) can you comment on the cmpss part?
  • Hi,

    To answer your second question first. If you refer to the technical reference manual, you will find the statement below:

    "The flag will remain set until cleared through the appropriate XBARCLRx register. " So it will be latched and that is the reason you didn't see the toggling.

    Regards,

    Chen

  • Hi,

    For your first question. When you said "having high inductor peak currents more than the set peak current limit." Are you suggesting the peak current mode does not work and the inductor current keeps going up after hitting the limit you set?

    Do you have any picture showing the PWM A/B signal you want together with the DCEVT signal which is related to the peak. I am trying to identify the issue. 

    Regards,

    Chen

  • Hi,

    Any updates?

    Regards,

    Chen

  • Chen,

    I have managed to get the CMPSS module working and have attached the following image with the following legend.
    Green = Top gate signal
    Pink = Bottom gate signal
    Blue = Inductor current

    I am now getting a shoot through with the top and bottom gate as there is no longer the dead time present. Is it possible to shut the top gate OFF immediately when there's a triggered compare AND turn ON the bottom gate after a predefined deadtime? Should I post this in another thread or can you direct me to an example?

  • Hi,

    You don't need to create another thread. Yes, you should be eble to do that by using T1 and T2 in the action-qualifier and add dead band accordingly.

    Below is a pic showing how we use this feature for peak current mode controlled phase shifted full bridge converter. T1U is the action when counter goes up and T1 occurs.

    We don't have an example code released publicly yet but that is should be in the near future.

    Regards,

    Chen