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.

F28075 Analog Comparators ePWM

Hi 

I want to implement hysterisis current controller and i use the analog comparators to get the set and reset signals. I know i can use the external flip flops and drive this flipflops from the comparator output.

But i want to eliminate the external flip flop and tried to use the PWM trip zone. Here comes the problem. Inorder to pull the pin either to high or low need one shot trip (OSHT). I need to use Digital compare submodule to generate the trip events. Digital compare module shall force events (DCAEVT1/2) based on the output signals from the comparators. DCxEVT1 is connected to the OSTH and DCxEVT2 is connected to the CBC. But DCAEVTx is connected to the trip event of ePWMxA module and DCBEVTx is connected to the trip event of ePWMxB module. This means only one event can control the PWM output and it’s not possible to add another event to control the same PWM output. This brings the bottle neck to set or reset the signal on signal changes in comparator submodule. 

On the bottom line, i need to realize SR flip flop logic with in the micro controller where the S and R inputs are driven by the high and low comparators of the CMPSS module. Is there any possibility to do this with F28075. 

  • Hi Karthick,

    You are largely correct in your understanding.  However, I am aware of two potential options which may help you (both of which have only been added in recent chips with Type 4 ePWM modules - like your 'F28075):

    1) In the TZ submodule:
    CBC/OSHT trip events can only make one event occur as you have stated.  However, one of the events is to "Toggle" the ePWM output.

    2) In the AQ submodule: 
    The PWM signal output from the AQ submodule can be modified by PRD, ZRO, CMPA, CMPB, T1 and T2 events.  The first four come from the timer, but the second two come from one of the asynchronous DCxEVTn or TZn signals.  Note that the AQ submodule is before many of the other submodules.  Because of this, asynchronous actions can now have deadband generated between the A & B outputs because of the Deadband submodule.  It also means that the Trip Zone submodule hasn't been used and therefore can be used to protect against serious faults.

    Hopefully this helps.


    Thank you,
    Brett

  • option#2 fits into my application. Configuring the T1 and T2 event works. But the trip zone control action must be disabled (TZCTL = 0xffff), so that the trip will not react.
  • Brett Larimore said:


    2) In the AQ submodule: 
    The PWM signal output from the AQ submodule can be modified by PRD, ZRO, CMPA, CMPB, T1 and T2 events.  The first four come from the timer, but the second two come from one of the asynchronous DCxEVTn or TZn signals.  Note that the AQ submodule is before many of the other submodules.  Because of this, asynchronous actions can now have deadband generated between the A & B outputs because of the Deadband submodule.  It also means that the Trip Zone submodule hasn't been used and therefore can be used to protect against serious faults.

    Hi Brett,

    In my application of peak current control with F28377D, I want to add deadband between PWM A/B. Because the deadband module precedes the TZ module, I read some posts that it was impossible to do this and you had to implement this either by additional PWMs or software. As I understand from your 2nd point, now it is possible to add deadband into comparator trip events! I checked it and works fine, I spent the whole day thinking ways to implement it by any other means.

    Thank you!

  • I did want to make note of one possible issue with this implementation (which may be important for some applications, but may not in others)...

    If you rely on the T1/T2 events to edit your PWM, changes to the PWM waveform will not take place immediately.  Instead they will synchronize to the next TBCLK.  The only way to make the PWM change state immediately (asynchronously) is to use the TZ submodule.

    -Brett

  • I am trying to implement the aforementioned current hysteresis control with F28377D using T1 and T2 event as per instruction from Brett,  Karthick and Panos.

    Unfortunately, I couldn't get it to work and got stuck for a few days. Could you please help me take a look. Any pointer is greatly appreciated. Thank you in advance.

    So for the comparator, I am using CMPSS1, and I initialize it as follows (I think this part of the code is set up correctly, so perhaps we can skip it first):

    void InitCMPSS1(void)

    {

       EALLOW;

       //Enable CMPSS

       Cmpss1Regs.COMPCTL.bit.COMPDACE            = 0x1;

       //NEG signal of High comparator comes from DAC

       Cmpss1Regs.COMPCTL.bit.COMPHSOURCE         = 0x0;

       //NEG signal of Low comparator comes from DAC

       Cmpss1Regs.COMPCTL.bit.COMPLSOURCE         = 0x0;

       //Use VDDA as the reference for DAC

       Cmpss1Regs.COMPDACCTL.bit.SELREF           = 0x0;

       // Load DACxVALA from its shadow registor (not the ramp generator)

       Cmpss1Regs.COMPDACCTL.bit.DACSOURCE        = 0x0;

       // Load DACxVALA immediately after loading its shadow registor

       Cmpss1Regs.COMPDACCTL.bit.SWLOADSEL        = 0x0;

       //Set DAC voltage level

       //High comparator get upper limit, so its output is normally low

       Cmpss1Regs.DACHVALS.bit.DACVAL             = COMP_MAX;

       //Low comparator get lower limit, so its output is normally high

       Cmpss1Regs.DACLVALS.bit.DACVAL             = COMP_MIN;

       //invert Low comparator signal since we use high to trigger PWM event

       Cmpss1Regs.COMPCTL.bit.COMPLINV         = 0x1;

       //do not invert Low comparator signal

       Cmpss1Regs.COMPCTL.bit.COMPHINV         = 0x0;

       // Configure Digital Filter

       /*

    //Maximum CLKPRESCALE value provides the most time between samples

    Cmpss1Regs.CTRIPHFILCLKCTL.bit.CLKPRESCALE = 0x3FF;

    //Maximum SAMPWIN value provides largest number of samples

    Cmpss1Regs.CTRIPHFILCTL.bit.SAMPWIN        = 0x1F;

    //Maximum THRESH value requires static value for entire window

    //  THRESH should be GREATER than half of SAMPWIN

    Cmpss1Regs.CTRIPHFILCTL.bit.THRESH         = 0x1F;

    //Reset filter logic & start filtering

    Cmpss1Regs.CTRIPHFILCTL.bit.FILINIT        = 1;

    */

    // Configure compare result output path

       //Asynch output feeds CTRIPH and CTRIPL

       Cmpss1Regs.COMPCTL.bit.CTRIPHSEL        = 0x0;

       Cmpss1Regs.COMPCTL.bit.CTRIPLSEL        = 0x0;

       //Asynch output feeds CTRIPOUTH and CTRIPOUTL

       Cmpss1Regs.COMPCTL.bit.CTRIPOUTHSEL        = 0x0;

       // Configure CTRIPOUTH output pin

       //Configure OUTPUTXBAR3 to be CTRIPOUT1H

       OutputXbarRegs.OUTPUT3MUX0TO15CFG.bit.MUX1 = 0;

       //Enable OUTPUTXBAR3 Mux for Output

       OutputXbarRegs.OUTPUT3MUXENABLE.bit.MUX1   = 1;

       // Configure GPIO14 to output CTRIPOUT1H

       GPIO_SetupPinMux(14, GPIO_MUX_CPU1, 6);

       // Configure CTRIPH output to ePWM X-BAR logic

       //Configure TRIP4 to be CMPSS1 CTRIPH (select MUX0.1)

       EPwmXbarRegs.TRIP4MUX0TO15CFG.bit.MUX0 = 0; //select .1 input

       //Configure TRIP5 to be CMPSS1 CTRIPL (select MUX1.1)

       EPwmXbarRegs.TRIP5MUX0TO15CFG.bit.MUX1 = 0; //select .1

       //Enable TRIP4 Mux for Output

       EPwmXbarRegs.TRIP4MUXENABLE.bit.MUX0   = 1;

       //Enable TRIP5 Mux for Output

       EPwmXbarRegs.TRIP5MUXENABLE.bit.MUX1   = 1;

       EDIS;

    }

    As you can see, I put the output of CMPSS1 (either CTRIPOUT1H  or CTRIPOUT1H )  to GPIO pin 14. I debug using external ramp signal to CMPIN1P, and the output on GPIO 14 react correctly, suggesting that the comparators are working OK. At the end of the above code, I connect CTRIPH to trip 4 and CTRIPL to trip 5 through ePWM X-BAR.

    Then I configure ePWM3 as follows:

    void InitEPwm3Example()

    {

    EALLOW;

      // Setup TBCLK

      EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up

      EPwm3Regs.TBPRD = EPWM_TIMER_TBPRD;       // Set timer period

      EPwm3Regs.TBCTL.bit.PHSEN = TB_DISABLE;    // Disable phase loading

      EPwm3Regs.TBPHS.bit.TBPHS = 0x0000;       // Phase is 0

      EPwm3Regs.TBCTR = 0x0000;                  // Clear counter

      EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV2;   // Clock ratio to SYSCLKOUT, EPWMCLK = SYSCLKOUT/2

      EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1;      //TBCLK =EPWMCLK/(HSPCLKDIV * CLKDIV)

      // Setup shadow register load on ZERO

      EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; //use shadow mode to load compare register

      EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;

      EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;

      EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

      // Set Compare values

      EPwm3Regs.CMPA.bit.CMPA = EPWM_CMPA;    // Set compare A value

      // Set actions

      //EPwm3Regs.AQCTLA.bit.ZRO = AQ_SET;            // Set PWM1A on Zero

      //EPwm3Regs.AQCTLA.bit.CAU = AQ_CLEAR;          // Clear PWM1A on event A, up count

      EPwm3Regs.AQTSRCSEL.bit.T1SEL = 0x0;            // select DCAEVT1 as T1 event source

      EPwm3Regs.AQTSRCSEL.bit.T2SEL = 0x2;                  // select DCBEV1 as T2 event source

      EPwm3Regs.AQCTLA2.bit.T1U = AQ_CLEAR;            // Set PWM1A upon T1 event

      EPwm3Regs.AQCTLA2.bit.T2U = AQ_SET;            // clear PWM1A upon T2 event

      // Set digital compare and trip zone

      // determine the input-ouptput logic of the Digital Comparator

      EPwm3Regs.TZDCSEL.bit.DCAEVT1          = TZ_DCAL_HI;  //generate DCAEVT1 (current signal hit upper limit)

                                  //when DCA low input (trip 4) is high, high input (trip 5) is low

      EPwm3Regs.TZDCSEL.bit.DCBEVT1          = TZ_DCBL_HI;  //generate DCBEVT1 when DCB low input is high, high input is low

      // make sure the DC event does no directly change the EPWMxA/B through trip zone

      EPwm3Regs.TZCTL.bit.DCAEVT1               = TZ_NO_CHANGE;  //do nothing on DCAEVT1

      EPwm3Regs.TZCTL.bit.DCBEVT1               = TZ_NO_CHANGE;  //do nothing on DCABVT1

      EPwm3Regs.TZCTL.bit.TZA                   = TZ_NO_CHANGE;  //do nothing

      EPwm3Regs.TZCTL.bit.TZB                   = TZ_NO_CHANGE;  //do nothing

       //Configure DCA input

       EPwm3Regs.DCTRIPSEL.bit.DCALCOMPSEL    = 0x3;  // DCA low input is trip 4

       EPwm3Regs.DCTRIPSEL.bit.DCALCOMPSEL    = 0x4;  // DCA high input is trip 5

       //Configure DCB input

       EPwm3Regs.DCTRIPSEL.bit.DCALCOMPSEL    = 0x4;  // DCB low input is trip 5

       EPwm3Regs.DCTRIPSEL.bit.DCALCOMPSEL    = 0x3;  // DCB high input is trip 4

       //Configure DCA path to be unfiltered & async

       EPwm3Regs.DCACTL.bit.EVT1SRCSEL        = DC_EVT1;

       EPwm3Regs.DCACTL.bit.EVT1FRCSYNCSEL    = DC_EVT_ASYNC;

       //Configure DCB path to be unfiltered & async

       EPwm3Regs.DCBCTL.bit.EVT1SRCSEL        = DC_EVT1;

       EPwm3Regs.DCBCTL.bit.EVT1FRCSYNCSEL    = DC_EVT_ASYNC;

      // Active high complementary PWMs - Setup the deadband

      EPwm3Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;

      EPwm3Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;

      EPwm3Regs.DBCTL.bit.IN_MODE = DBA_ALL;

      EPwm3Regs.DBRED = EPWM_DB;

      EPwm3Regs.DBFED = EPWM_DB;

      EDIS;

    }

    I changed the input to CMPIN1P, I can see GPIO 14 changes accordingly. However, the ePWM3A/B does not change ( one is high and one is low). In the ePWM3 initialization code above, if I uncomment

      // Set actions

      //EPwm3Regs.AQCTLA.bit.ZRO = AQ_SET;            // Set PWM1A on Zero

      //EPwm3Regs.AQCTLA.bit.CAU = AQ_CLEAR;          // Clear PWM1A on event A, up count

    Then I can observe a fixed duty PWM as expected. But the PWM just won't change with CMPIN1P. When I look at the register in ccs debug, it seems that DCBEVT1 always happen, and it stays that not changing anymore, even if I change the input to CMPIN1P, or flip the connection of trip 4 and trip 5, etc.

    Any suggestions? Thank you very much!

  • Hi Shibin,

    To be honest, I didn't check carefully your code, but I will do it. Firstly, I think that the DCAEVT1 is for one shot trigger only, so you have to clear the event when it stops to be present in order to repeat it again, or you can use the DCAEVT2 for CBC. Secondly, If you use DB fully enabled, I think that you do not need to create events for DCB. In my case, every cycle the PWMA is high at the start of the cycle and when an event occurs, it is forced to low. To configure PWMB, I used DB and T1 event. You can use the example in the device support folder for one shot triggering.

    Thanks,
    Panos
  • Hello Panos,

    Thank you very much for your reply. I was trying to implement a current hysteresis control with both upper and lower limit, so I set up the two comparators in CMPSS1. When the signal is within the limit, COMPH in CPMSS1 output low while COMPL output high, but I inverted COMPL output, so both are normally low. When the current hit one of the limit, it will create a high output, which is sent to ePWM3 digital comparator through ePWM-Xbar. This is what I am trying to do.

    When I used DCAEVT2 and DCBEVT2 instead of one, DCBEVT2 always stay 1, while DCAEVT2 stays 0, regardless of the input to CMPIN1P.....

  • Hello Panos, 

    Thank you for your help. I finally get it working using DCAEVT2. I am still not sure why it wasn't working since I change a lot things back and forth, but now I have a working version of the code. Here it is. Hopefully it will be helpful to other people trying to implement this as well. 

    EALLOW;
    // Enable PWM
    EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
    //Configure EPWM to run at SYSCLK
    EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV2; // Clock ratio to SYSCLKOUT, EPWMCLK = SYSCLKOUT/2
    EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1; //TBCLK =EPWMCLK/(HSPCLKDIV * CLKDIV)
    EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Disable phase loading
    EPwm3Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0
    EPwm3Regs.TBCTR = 0x0000; // Clear counter
    EPwm3Regs.TBPRD = EPWM_TIMER_TBPRD; // Set timer period
    // Set Compare values
    EPwm3Regs.CMPA.bit.CMPA = EPWM_CMPA; // Set compare A value


    // Setup shadow register load on ZERO
    EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; //use shadow mode to load compare register
    EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

    // Set actions
    EPwm3Regs.AQTSRCSEL.bit.T1SEL = 0x1; // select DCAEVT2 as T1 event source
    EPwm3Regs.AQTSRCSEL.bit.T2SEL = 0x3; // select DCBEVT2 as T2 event source
    EPwm3Regs.AQCTLA2.bit.T1U = AQ_CLEAR; // Set PWM1A upon T1 event
    EPwm3Regs.AQCTLA2.bit.T2U = AQ_SET; // clear PWM1A upon T2 event

    // Set digital compare and trip zone
    // determine the input-ouptput logic of the Digital Comparator
    EPwm3Regs.TZDCSEL.bit.DCAEVT2 = TZ_DCAL_HI_DCAH_LOW; //generate DCAEVT1 (current signal hit upper limit)
    //when DCA low input (trip 4) is high, high input (trip 5) is low
    // be careful how to connect trip input to DC later
    EPwm3Regs.TZDCSEL.bit.DCBEVT2 = TZ_DCAL_HI_DCAH_LOW; //generate DCBEVT1 when DCB low input is high, high input is low

    //Configure DCA input
    EPwm3Regs.DCTRIPSEL.bit.DCALCOMPSEL = 0x3; // DCA low input is trip 4
    EPwm3Regs.DCTRIPSEL.bit.DCAHCOMPSEL = 0x4; // DCA high input is trip 4
    //Configure DCB input
    EPwm3Regs.DCTRIPSEL.bit.DCBLCOMPSEL = 0x4; // DCB low input is trip 5
    EPwm3Regs.DCTRIPSEL.bit.DCBHCOMPSEL = 0x3; // DCB high input is trip 4


    //Configure DCA path to be unfiltered & async
    EPwm3Regs.DCACTL.bit.EVT2SRCSEL = DC_EVT2;
    EPwm3Regs.DCACTL.bit.EVT2FRCSYNCSEL = DC_EVT_ASYNC;
    //Configure DCB path to be unfiltered & async
    EPwm3Regs.DCBCTL.bit.EVT2SRCSEL = DC_EVT2;
    EPwm3Regs.DCBCTL.bit.EVT2FRCSYNCSEL = DC_EVT_ASYNC;

    // make sure the DC event does no directly change the EPWMxA/B through trip zone
    EPwm3Regs.TZCTL.bit.DCAEVT2 = TZ_NO_CHANGE; //do nothing on DCAEVT1
    EPwm3Regs.TZCTL.bit.DCBEVT2 = TZ_NO_CHANGE; //do nothing on DCABVT1
    EPwm3Regs.TZCTL.bit.TZA = TZ_NO_CHANGE; //do nothing
    EPwm3Regs.TZCTL.bit.TZB = TZ_NO_CHANGE; //do nothing

    // Configure CTRIPH output to ePWM X-BAR logic
    //Configure TRIP4 to be CMPSS1 CTRIPH (select MUX0.1)
    EPwmXbarRegs.TRIP4MUX0TO15CFG.bit.MUX0 = 0; //select .1 input
    //Configure TRIP5 to be CMPSS1 CTRIPL (select MUX1.1)
    EPwmXbarRegs.TRIP5MUX0TO15CFG.bit.MUX1 = 0; //select .1
    //Enable TRIP4 Mux for Output
    EPwmXbarRegs.TRIP4MUXENABLE.bit.MUX0 = 1;
    //Enable TRIP5 Mux for Output
    EPwmXbarRegs.TRIP5MUXENABLE.bit.MUX1 = 1;

    // Active high complementary PWMs - Setup the deadband
    EPwm3Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
    EPwm3Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
    EPwm3Regs.DBCTL.bit.IN_MODE = DBA_ALL;
    EPwm3Regs.DBRED = EPWM_DB;
    EPwm3Regs.DBFED = EPWM_DB;

  • Hi Shibin,

    It is nice to hear that you found a solution. I checked a little more your code. The only that I found is that when an trigger event occurs, you do not clear the flag of this event. I think that it would be better if you used DCAEVT1 and cleared the flag when the comparator trip is de-asserted. As is in the example in the device support folder. When you use DCAEVT2, at every PWM cycle the flag is cleared automatically.

    Good luck with your code.

    Thanks,

    Panos