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: Issue using the Digital Compare Module for EPWM tripping

Part Number: LAUNCHXL-F280049C

Tool/software: Code Composer Studio

Hello ladies and gentlemen,

(TL;DR version below) I'm trying to implement a peak current-mode control for a boost converter on the LAUNCHXL-F280049C. I am using one of the analog comparator submodules (Cmpss2) to measure a voltage supplied by a DC voltage source to the pin J7-69 (ADCINA3 / PGA2_IN). This voltage is fed to the positive input of the COMPH comparator (CMP2_HP2) and compared to the value specified in the Cmpss2Regs.DACHVALS register on the negative comparator input. The output of the comparator is then routed to the Digital Compare submodule via the EPWM X-Bar. The signal is muxed to DCAH using the EPwm1Regs.DCTRIPSEL register. I have set the condition for a DCAEVT1 event to occur (which forces my EPWM1A output "low") within the EPwm1Regs.TZDCSEL register to be "DCAH = high, DCAL = don't care". This means that the analog comparator output has to be "high" for a DCAEVT1 to occur, if I am not mistaken.

Now, after starting the program on my F280049C, the EPWM1A output is constantly "low" after applying the above configurations. I have set the value in the Cmpss2Regs.DACHVALS register to 1024 for testing, which should require the positive input voltage to be about (3.3V * 1024 / 4096) = 0.825V to create a "high" analog comparator output and therefore a Digital Compare event, which in turn pulls the PWM "low". However, as I said, the PWM output is constantly "low", whether I am applying a voltage above or below 0.825V.

If I choose a different condition in the EPwm1Regs.TZDCSEL register, or if I disable the analog comparator so no signal can be passed to DCAH, then DCAEVT1 events do not happen and my PWM output looks as usual. So, looking at Figure 18-48 on page 1872 in the reference manual (sprui33c), I am now assuming that there must be an issue with the DCAH or DCAL signals and how they create a DCAEVT1 event. The TZFLG[DCAEVT1] register shows that, indeed, an event has happened, but I am unsure what exactly happens before that.

Interestingly, though I don't know if that helps solving my issue: If I set EPwm1Regs.TZDCSEL.bit.DCAEVT1 = 1  so that the condition "DCAH = low, DCAL = don't care" creates a DCAEVT1 event, no event happens regardless of the voltage fed to the positive analog comparator input. If I then force a DCAEVT1 using the EPwm1Regs.TZFRC register, the PWM constantly ouputs "low" (as can be expected), this change can not be reverted even after clearing the corresponding TZFLG flag or changing the EPwm1Regs.TZDCSEL.bit.DCAEVT1 value, so the PWM output stays "low".

TL;DR: So what I want to achieve now is that the EPWM1A output is only pulled "low" when the voltage supplied to the analog comparator is above 0.825V (for instance) and that the PWM output continues to behave as usual as soon as the voltage decreases back to 0.825V or below. I hope the parts of my code below will help finding the mistake I probably made:

void initPWM()
{
	EALLOW;

	// Define PWM period and duty cycle
	EPwm1Regs.TBPRD = Tp; 
	EPwm1Regs.CMPA.bit.CMPA = duty*EPwm1Regs.TBPRD;

	// Various PWM settings
	EPwm1Regs.TBCTL.bit.CTRMODE   = 0;   // Count up only mode
	EPwm1Regs.TBCTL.bit.PRDLD     = 1;       // TBPRD can only be written directly
	EPwm1Regs.TBCTL.bit.CLKDIV    = 0;       // PWM Clk Divider = 1
	EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;   // High Speed PWM Clk Divider = 1
	EPwm1Regs.TBCTL.bit.FREE_SOFT = 2;  // Counter never stops

	// Action Qualifier settings
	EPwm1Regs.AQCTLA.bit.PRD      = 2;   // Output "High" when CNT = TPRD
	EPwm1Regs.AQCTLA.bit.CAU      = 1;   // Output "Low" wenn CNT = CMPA

	// Digital Compare and Trip Zone settings
	EPwm1Regs.DCTRIPSEL.bit.DCAHCOMPSEL = 3;    // Digital Compare A High Input (TRIPIN4 is muxed to DCAH)
	EPwm1Regs.DCACTL.bit.EVT1SRCSEL = 0;              // Source is DCAEVT1 signal 
	EPwm1Regs.DCACTL.bit.EVT1FRCSYNCSEL = 0;    // Source is passed through asynchronously
	EPwm1Regs.TZSEL.bit.DCAEVT1 = 1;                       // Enable DCAEVT1 as a cycle-by-cycle trip source for ePWM1
	EPwm1Regs.TZDCSEL.bit.DCAEVT1 = 2;                  // DCAEVT1 caused when: DCAH = high, DCAL = don't care    
	EPwm1Regs.TZCTL.bit.DCAEVT1 = 2;                       // Force EPWM1A output "low" when a DCAEVT1 event occurs

	EDIS;
}

void initComparator(void)
{
	EALLOW;

	AnalogSubsysRegs.CMPHPMXSEL.bit.CMP2HPMXSEL = 2;   // Select CMP2_HP2 (positive comparator input)
	CpuSysRegs.PCLKCR14.bit.CMPSS2 = 1;                                // Enable CMPSS2 (Comparator 2) Clock
	Cmpss2Regs.COMPCTL.bit.COMPDACE = 1;                          // Comparator 2 / DAC enable
	Cmpss2Regs.COMPCTL.bit.COMPHSOURCE = 0;                  // Negative comparator input is fed internally by DACHVALS
	Cmpss2Regs.DACHVALS.bit.DACVAL = 1024;                         // Negative comparator input value: DACVAL*3.3V/4096 in volts
	EPwmXbarRegs.TRIP4MUX0TO15CFG.bit.MUX2 = 1;            // Comparator 2 output (CMPSS2.CTRIPH) is muxed to TRIP4
	EPwmXbarRegs.TRIP4MUXENABLE.bit.MUX2 = 1;                // Enable MUX2

	EDIS;
}

Any help is appreciated and I am greatly looking forward to your answers.

Kind regards,
Willem

  • Hi Willem,

    Some of the CMPSS actions are a bit bizzare and not well documented how the MUX defines translate into ePWM DC events. Perhaps using C2000 driverlib calls to configure these peripherals, then most anyone can easily help you.

    Several of my CMPSS posts seem related to what you are seeing and may help you. There are also trip flags that should be cleared after anyone of several configured DC 1A/B (OSHT) or 2A/2B (CBC) events occur.  

    Regards,

  • I definitely recommend driverlib if youre not extremely familiar with the device.

    I have written some examples for the DC submodule.

    Take a look at this.

    http://dev.ti.com/tirex/explore/node?node=AC.EcgFkTyhV-.pvtOgpVw__gYkahfz__LATEST

    http://dev.ti.com/tirex/explore/node?node=ANR0oEyrhX8GzAIDuglGgg__gYkahfz__LATEST

    http://dev.ti.com/tirex/explore/node?node=ACkFBDkWmaKVG9EEZcqo9w__gYkahfz__LATEST

    http://dev.ti.com/tirex/explore/node?node=AIkKlYDJ1Sdd2ShHn1jSLA__gYkahfz__LATEST

    Can you also share a couple of bullet pointed questions that I can focus on answering?

  • GI said:

    Hi Willem,

    Some of the CMPSS actions are a bit bizzare and not well documented how the MUX defines translate into ePWM DC events. Perhaps using C2000 driverlib calls to configure these peripherals, then most anyone can easily help you.

    Several of my CMPSS posts seem related to what you are seeing and may help you. There are also trip flags that should be cleared after anyone of several configured DC 1A/B (OSHT) or 2A/2B (CBC) events occur.  

    Regards,

    Hi GI,

    I think it hasn't quite come clear from my post, but the CMPSS output actually works (which I can check using the Cmpss2Regs.COMSTS register). What does not work is how the DC module responds to that signal delivered by DCAH (the analog comparator output). I'll check your posts on friday and will then report back.

    Nima Eskandari said:

    I definitely recommend driverlib if youre not extremely familiar with the device.

    I have written some examples for the DC submodule.

    Take a look at this.

    http://dev.ti.com/tirex/explore/node?node=AC.EcgFkTyhV-.pvtOgpVw__gYkahfz__LATEST

    http://dev.ti.com/tirex/explore/node?node=ANR0oEyrhX8GzAIDuglGgg__gYkahfz__LATEST

    http://dev.ti.com/tirex/explore/node?node=ACkFBDkWmaKVG9EEZcqo9w__gYkahfz__LATEST

    http://dev.ti.com/tirex/explore/node?node=AIkKlYDJ1Sdd2ShHn1jSLA__gYkahfz__LATEST

    Can you also share a couple of bullet pointed questions that I can focus on answering?

    Hi Nima,

    personally I am not very fond of driverlib functions because I find it harder to understand what they do. I'll try them instead of bitfield operations anyway on friday and report back if that worked. Your example in the second link "epwm_ex5_digital_compare_event_filter" is actually what I tried to replicate using bitfield operations, though that didn't work yet as you can see from my code example above. I will try the driverlib functions later. Regarding my questions:

    • The DCAEVT1 condition in the TZDCSEL register is defined to be "DCAH: "high", DCAL: don't care". Why are DCAEVT1 events created even though the DCAH input is supposedly not "high"? (the DCAH signal is supplied by the CMPSS output, and the CMPSS module works as I checked it using the COMSTS register)
    • Is there a way to check the current DCAH status in case I have made a mistake and my analog comparator output is not actually correctly routed to DCAH?
    • Once a DCAEVT1 is created and my EPWM1A output is pulled "low" by DCAEVT1.force, why can't I pull the PWM output back "high" even after clearing the TZFLG flag (to signalize that the DCAEVT1 condition is over)?

    I hope these questions help.

    Kind regards,
    Willem

  • Willem Biermann said:

    Hi Nima,

    personally I am not very fond of driverlib functions because I find it harder to understand what they do. I'll try them instead of bitfield operations anyway on friday and report back if that worked. Your example in the second link "epwm_ex5_digital_compare_event_filter" is actually what I tried to replicate using bitfield operations, though that didn't work yet as you can see from my code example above. I will try the driverlib functions later. Regarding my questions:

    • The DCAEVT1 condition in the TZDCSEL register is defined to be "DCAH: "high", DCAL: don't care". Why are DCAEVT1 events created even though the DCAH input is supposedly not "high"? (the DCAH signal is supplied by the CMPSS output, and the CMPSS module works as I checked it using the COMSTS register)
    • Is there a way to check the current DCAH status in case I have made a mistake and my analog comparator output is not actually correctly routed to DCAH?
    • Once a DCAEVT1 is created and my EPWM1A output is pulled "low" by DCAEVT1.force, why can't I pull the PWM output back "high" even after clearing the TZFLG flag (to signalize that the DCAEVT1 condition is over)?

    I hope these questions help.

    Kind regards,
    Willem

    Hi everyone,

    so the third bullet point is solved. What I wanted to use is the cycle-by-cycle trip which the DCAEVT2 is designed for, while I used DCAEVT1 which is for one-shot trips.

    However, the first two questions remain. I have used the driverlib functions as you suggested and I used this example:

    dev.ti.com/.../node

    I replaced the DC and TZ bitfield settings in my code by the following functions:

    void initPWM()
    {
        EALLOW;
    
        // Define PWM period and duty cycle
        EPwm1Regs.TBPRD = Tp; 
        EPwm1Regs.CMPA.bit.CMPA = duty*EPwm1Regs.TBPRD;
    
        // Various PWM settings
        EPwm1Regs.TBCTL.bit.CTRMODE   = 0;   // Count up only mode
        EPwm1Regs.TBCTL.bit.PRDLD     = 1;       // TBPRD can only be written directly
        EPwm1Regs.TBCTL.bit.CLKDIV    = 0;       // PWM Clk Divider = 1
        EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;   // High Speed PWM Clk Divider = 1
        EPwm1Regs.TBCTL.bit.FREE_SOFT = 2;  // Counter never stops
    
        // Action Qualifier settings
        EPwm1Regs.AQCTLA.bit.PRD      = 2;   // Output "High" when CNT = TPRD
        EPwm1Regs.AQCTLA.bit.CAU      = 1;   // Output "Low" wenn CNT = CMPA
    
        // Digital Compare and Trip Zone settings
        EPwm1Regs.DCTRIPSEL.bit.DCAHCOMPSEL = 3;    // Digital Compare A High Input (TRIPIN4 is muxed to DCAH)
    
        // Select TRIPIN4 as source for DCAH
        EPWM_selectDigitalCompareTripInput(EPWM1_BASE, EPWM_DC_TRIP_TRIPIN4, EPWM_DC_TYPE_DCAH);
    
        // Create DCAEVT2 event when DCAH is "high"
        EPWM_setTripZoneDigitalCompareEventCondition(EPWM1_BASE, EPWM_TZ_DC_OUTPUT_A2, EPWM_TZ_EVENT_DCXH_HIGH);
    
        // DCAEVT2 source is unfiltered
        EPWM_setDigitalCompareEventSource(EPWM1_BASE, EPWM_DC_MODULE_A, EPWM_DC_EVENT_2, EPWM_DC_EVENT_SOURCE_ORIG_SIGNAL);
        
        // DCAEVT2 events pull the EPWM1 output "low"
        EPWM_setTripZoneAction(EPWM1_BASE, EPWM_TZ_ACTION_EVENT_DCAEVT2, EPWM_TZ_ACTION_LOW);
    
        EDIS;
    }
    
    

    However, the outcome is still exactly the same depending on the state of the EPwm1Regs.TZDCSEL.bit.DCAEVT2 register:

    • EPwm1Regs.TZDCSEL.bit.DCAEVT2 = 2  or  4:  DCAEVT2 events are constantly created and the EPWM1A output is always "low" regardless of my CMPSS output.
    • EPwm1Regs.TZDCSEL.bit.DCAEVT2 = 0, 3 or 5: DCAEVT2 events never happen and the EPWM1A is active as usual regardless of my CMPSS output.

    Another problem I encountered, though I don't know if this is any helpful: if I try to force the EPWM1A output "high" instead of "low" using DCAEVT2 events, the output is still always low.

    I am still suspecting that there must be something wrong with how DCAEVT2 events are created in the "Event A Qual" (looking at figure 18-49 on page 1872 in the ref manual) depending on the DCAH input. Either that, or I have incorrectly routed my CMPSS output to DCAH, but if so, then I can't find the mistake and there is no flag register to help me find it. I have also tried a second board to see if there is any hardware damage, but the result is still completely the same.

    Any further help regarding my issue is greatly appreciated.

    Kind regards,
    Willem

  • Hi,

    I have found the error. This is the bit I have set incorrectly and somehow forgot about when I was troubleshooting later on:

    EPwmXbarRegs.TRIP4MUX0TO15CFG.bit.MUX2 = 1;     // Comparator 2 output (CMPSS2.CTRIPH) is muxed to TRIP4

    Which should have been set to =0 to mux only CMPSS2.CTRIPH signals to TRIP4. Before, both CTRIPH and CTRIPL outputs were muxed to TRIP4. Now everything works as it should.

    Kind regards,
    Willem