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.

TMS320F28027: TMS320F28027

Part Number: TMS320F28027

Dear all,

I am studying on TMS320F28027 and I am trying to synchronise PWM output with analog comparator signal. To achive that, I am creating an event signal (DCAEVT1) for low and high level of comparator and going a tripzone interrupt.

When controller recieves SWFSYNC signal, PWM module is supposed to load 0 (zero) as phase value and it will load pwm counter register with zero. Thus, pwm will be restarted.

I have two problem on that step;

The first one is; SWFSYN register cannot be set 1. It is alwasy zero. Therefore, I cannot get synchronise signal.

The second one is; When I set PHSEN bit as 1, which is located in PWM registers, TBCTL register, PWM output is always high. I can observe a high level output.It never goes down.

Best Regards,

Fahri

  • Hi;
    For the same problem;
    When I am using direct access register, PWM is not changing polarity it is always high.
    When I replace it software drive code, code manage to load counter from phase register, But still I do not have stable output from PWM. It is still lock on high level.

    My register values;
    PHSEN : 1(Load counter from phase reg. when synchronization pulse is occured)
    PHSDIR : 1 (Count up after synchronization)
    SYNCOSEL : 0 (EPWMxSYNC)
    SWFSYNC : 1 (Enable)
    CTRMODE : 2(up-down count)
    TBPHS : 0 (Phase value)
    PWM frequency : 20KHz

    I need immediate help.

    Regards
    Fahri
  • Fahri,

    Are you checking for the trip behavior while the device is free-running or while halted?

    Can you describe how you have the Action-Qualifier and Trip-Zone modules configured?

    -Tommy

  • Hi Tommy

    Thank you for your interest.

    Analog comparator is connected to the tripzone submodule. Input of the analag comp. is sin wave and inverting input is connected to the DAC. When comp. is high, TZ interrupt occures and in interrupt, it is calculating comparator low level time. After that, it sets itself for comparator low level interrupt to get interrupt onec for same level.

    While I check for free run, I observe PWM does not change polarity. It is always high.

    If I check it with break point, sometimes it goes low.

    Here is my PWM configuration

    void InitEPwm1Example()
    	{
    
    	    CLK_enablePwmClock(myClk, PWM_Number_1);
    
    	    // Setup TBCLK
    	    //PWM_setPeriod(myPwm1, EPWM1_TIMER_TBPRD);   // Set timer period 801 TBCLKs
    	    EPwm1Regs.TBPRD=2500;		//set initial pwm frequency 20KHz
    	    //PWM_setPhase(myPwm1, 0x0000);               // Phase is 0
    	    EPwm1Regs.TBPHS.half.TBPHS=0;				//phase reg is 0
    	    //PWM_setCount(myPwm1, 0x0000);               // Clear counter
    	    EPwm1Regs.TBCTR=0;          //reset pwm counter
    
    	    //PWM_setCmpA(myPwm1, 1250); //%50 duty cycle olacak şekilde ayarlandı.
     	    //PWM_setCmpB(myPwm1, 1250); //%50 duty cycle olacak şekilde ayarlandı.
     	    EPwm1Regs.CMPA.half.CMPA=1250;
     	    EPwm1Regs.CMPB=1250;
    
    	    // Setup counter mode
    	    PWM_setCounterMode(myPwm1, PWM_CounterMode_UpDown); // Count up&down
    	    //PWM_disableCounterLoad(myPwm1);                     // Disable phase loading
    	    //Enable Phase loading
    	    EPwm1Regs.TBCTL.bit.PHSEN=1; 		//load TBC with phase reg. when EPWMSYNI input occure PHSEN 1 yapınca PWM çalışmıyor.
    	    EPwm1Regs.TBCTL.bit.PHSDIR=1;		//Set as up counting when phase register load counter
    	    EPwm1Regs.TBCTL.bit.SYNCOSEL=TB_SYNC_IN;
    
    	    PWM_setHighSpeedClkDiv(myPwm1, PWM_HspClkDiv_by_1); // Clock ratio to SYSCLKOUT
    	    PWM_setClkDiv(myPwm1, PWM_ClkDiv_by_1);
    
    	    //Setup shadowing, shadowing allows the register update to be synchronized with the hardware, shadow register provides a temporary holding location for the active register
    	    PWM_setShadowMode_CmpA(myPwm1, PWM_ShadowMode_Shadow);		//Enable shadow mode
    	    PWM_setShadowMode_CmpB(myPwm1, PWM_ShadowMode_Shadow);
    	    PWM_setLoadMode_CmpA(myPwm1, PWM_LoadMode_Zero);			//Load CMP when TBCTR=0
    	    PWM_setLoadMode_CmpB(myPwm1, PWM_LoadMode_Zero);
    
    	    // Set actions
    	    PWM_setActionQual_CntUp_CmpA_PwmA(myPwm1, PWM_ActionQual_Set);      // Set PWM1A on event A, up count
    	    PWM_setActionQual_CntDown_CmpA_PwmA(myPwm1, PWM_ActionQual_Clear);  // Clear PWM1A on event A, down count
    
    	    PWM_setActionQual_CntUp_CmpA_PwmB(myPwm1, PWM_ActionQual_Clear);      // Clear PWM1B on event B, up count
    	    PWM_setActionQual_CntDown_CmpA_PwmB(myPwm1, PWM_ActionQual_Set);  // Set PWM1B on event B, down count
    
    	    //CmpA ve CmpB birbirinin tersi olması için "clear" ve "set" flagleri yer değiştirildi.(cmpB'deki değiştirildi.)
    
    	    // Active high complementary PWMs - Setup the deadband
    	    PWM_setDeadBandOutputMode(myPwm1, PWM_DeadBandOutputMode_EPWMxA_Rising_EPWMxB_Falling);
    	    PWM_setDeadBandPolarity(myPwm1, PWM_DeadBandPolarity_EPWMxB_Inverted);
    	    PWM_setDeadBandInputMode(myPwm1, PWM_DeadBandInputMode_EPWMxA_Rising_and_Falling);
    	    //PWM_setDeadBandRisingEdgeDelay(myPwm1, 250);  //RED=2.5us(250)
    	    //PWM_setDeadBandFallingEdgeDelay(myPwm1, 250); //FED=2.5us(250)
    	    EPwm1Regs.DBRED=0;
    	    EPwm1Regs.DBFED=0;
    
    	    // Enable DCAEVT1 and DCBEVT1 are one shot trip sources
    	    //PWM_enableTripZoneSrc(myPwm1, PWM_TripZoneSrc_OneShot_CmpA);
    	    //PWM_enableTripZoneSrc(myPwm1, PWM_TripZoneSrc_OneShot_CmpB);
    
    	    // What do we want the DCAEVT1 and DCBEVT1 events to do?
    	    // DCAEVTx events can force EPWMxA
    	    // DCBEVTx events can force EPWMxB
    	    PWM_setTripZoneState_TZA(myPwm1, PWM_TripZoneState_DoNothing);  // EPWM1A will do nothing
    	    PWM_setTripZoneState_TZB(myPwm1, PWM_TripZoneState_DoNothing);   // EPWM1B will do nothing
    
    	    // Enable TZ interrupt
    	    PWM_enableTripZoneInt(myPwm1, PWM_TripZoneFlag_OST);
    
    	    // Interrupt where we will change the Compare Values
    	    PWM_setIntMode(myPwm1, PWM_IntMode_CounterEqualZero);   // Select INT on Zero event
    	    PWM_enableInt(myPwm1);                                  // Enable INT
    	    PWM_setIntPeriod(myPwm1, PWM_IntPeriod_ThirdEvent);     // Generate INT on 3rd event
    
    	    // Information this example uses to keep track
    	    // of the direction the CMPA/CMPB values are
    	    // moving, the min and max allowed values and
    	    // a pointer to the correct ePWM registers
    	    epwm1_info.EPwm_CMPA_Direction = EPWM_CMP_UP;   // Start by increasing CMPA &
    	    epwm1_info.EPwm_CMPB_Direction = EPWM_CMP_DOWN; // decreasing CMPB
    	    epwm1_info.EPwmTimerIntCount = 0;               // Zero the interrupt counter
    	    epwm1_info.myPwmHandle = myPwm1;                // Set the pointer to the ePWM module
    
    	}
    

    and tripzone configuration

            EALLOW;
            EPwm1Regs.DCTRIPSEL.bit.DCAHCOMPSEL = DC_COMP2OUT;   // DCAH = Comparator 2 output
            EPwm1Regs.DCTRIPSEL.bit.DCALCOMPSEL = DC_TZ2;        // DCAL = TZ2
            EPwm1Regs.TZDCSEL.bit.DCAEVT1 = TZ_DCAH_HI;   //generates event for comparator high for initialization
            EPwm1Regs.DCACTL.bit.EVT1SRCSEL = DC_EVT1;    //unfiltered signal
            EPwm1Regs.DCACTL.bit.EVT1FRCSYNCSEL = DC_EVT_ASYNC;
            EPwm1Regs.TZSEL.bit.DCAEVT1 = 1;
            //EPwm1Regs.TZSEL.bit.DCBEVT1 = 1;
            EDIS;

    And this one is what I am doing in interrupt

    interrupt void epwm1_tzint_isr(void)
    	{
    
    	    //GPIO_toggle(myGpio, GPIO_Number_6);
    	    /*EALLOW;
    	    GpioDataRegs.GPASET.bit.GPIO28=0;  //set high
    	    EDIS;*/
    	    // Clear the flags - we will continue to take
    	    // this interrupt until the TZ pin goes high
    
    /*	    EALLOW;
    	    CpuTimer0Regs.TCR.bit.TSS = 1; //Stop timer
    	    EDIS;
    */
    	    //#########################################
    	    //##### Adjust Tripzone interrupt condition
    	    //#########################################
    	    if (EPwm1Regs.TZDCSEL.bit.DCAEVT1==2)
    	    	{
    	    	EALLOW;
    	    	EPwm1Regs.TZDCSEL.bit.DCAEVT1 = 1;
    	    //GpioDataRegs.GPASET.bit.GPIO6=1;  //set high
    		 //t1=TIMER_getCount(myTimer);
    		 t2=65535-CpuTimer0Regs.TIM.all;
    		 CpuTimer0Regs.TCR.bit.TRB = 1;  //Timer reload
    	    	EDIS;
    	    	}
    	    else if (EPwm1Regs.TZDCSEL.bit.DCAEVT1==1)
        		{
        		EALLOW;
        		EPwm1Regs.TZDCSEL.bit.DCAEVT1 = 2;
        	        //GpioDataRegs.GPACLEAR.bit.GPIO6=1;  //set low
        	        //t2=TIMER_getCount(myTimer);
        	        t1=65535-CpuTimer0Regs.TIM.all;
        	        CpuTimer0Regs.TCR.bit.TRB = 1;  //Timer reload
        		EDIS;
        		}
    
    	    //digital PLL için (bu kısım incelenecek)
    	    tpwm=(t1+t2)>>1;
    	    //EPwm1Regs.TBPRD=tpwm;		//update pwm frequency
    	    //EPwm1Regs.TBCTL.bit.PRDLD=1;
    	    EPwm1Regs.TBCTL.bit.SWFSYNC=1;
    	    asm (" NOP");
    	    asm (" NOP");
    	    asm (" NOP");
    	    asm (" NOP");
    	    asm (" NOP");
    	    asm (" NOP");
    	    asm (" NOP");
    	    asm (" NOP");
    	    asm (" NOP");
    	    asm (" NOP");
    	    asm (" NOP");
    	    asm (" NOP");
    	    //PWM_forceSync(myPwm1);
    
    		n[EPwm1TZIntCount] = EPwm1Regs.TBSTS.all;
    	    EPwm1TZIntCount++;
    	    if (EPwm1TZIntCount==150)
    	    {
    	    	EPwm1TZIntCount = 0;
    	    }

    I can see that SWFSYNC is working ofter adding asm("NOP")

    But still I have no PWM output.

  • Fahri,

    Are you clearing the OST trip in the ISR?

    Can you check the contents of the TZCTL register and make sure that the only enabled actions are the ones that you want?

    It looks like you are modifying your TZDCSEL trip conditions in the ISR. If you can you attach some figures to illustrate what you want the EPWM outputs to do relative to the comparator input we might be able to give you some recommendations so that the TZDCSEL updates are not necessary.

    Also, it may be a good idea to incrementally build your EPWM configuration starting with just one EPWM output signal and no dead-band. Each feature has the potential to break the EPWM output if something is not configured correctly.

    -Tommy
  • Hi Tommy

    Thank you very much for your attention.

    I have figured out the problem. My PWM counter is up-down counter. At the first cycle, comparator sets PWM as high when a match occures. To make PWM low, it must count down and catch a matching again, but it resets counter before a count down matching.

    Thus, the action qualifier cannot set PWM output low. Therefore, I see continuous high level for PWM.

    I have changed counter as up counter.

    Thank you for your idea again.

    Regards

    Fahri