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.

TMS320F28377D: Problem with ShadowMode of EPWM

Part Number: TMS320F28377D

Hi,

I have weird problem with shadowing.

1) I set CMPCTL.SHDWAMODE = 0. Now I can change CMPA value - this is fine.

2) I set CMPA value for example to 1234, then change CMPCTL.SHDWAMODE from 0 to 1, I can not change CMPA value beaceuse value will immeditly restore to previous CMPA value.

3) I'm changing back to CMPCTL.SHDWAMODE to 0, now I can change CMPA value. I change LOADAMODE from 00b to 11b (freeze mode), but I still can change value for CMPA even when LOADAMODE is in freeze mode.

4) All tests I'm doing from CCS but code behave same

5) Also changing LOADAMODE with SHDWAMODE == 0 doesn't change anything.

Register startup code:

    EPwmxRegs->CMPCTL.bit.SHDWAMODE = CC_SHADOW;                                                // tryb shadow dla rejestrów EPWMxA jest aktywny
    EPwmxRegs->CMPCTL.bit.SHDWBMODE = CC_SHADOW;                                                // tryb shadow dla rejestrów EPWMxB jest aktywny
    EPwmxRegs->CMPCTL.bit.LOADAMODE = CC_CTR_PRD;                                               // nowa wartość wypełnienia A będzie ładowana, gdy główny licznik będzie równy PRD
    EPwmxRegs->CMPCTL.bit.LOADBMODE = CC_CTR_PRD;                                               // nowa wartość wypełnienia B będzie ładowana, gdy główny licznik będzie równy PRD
                                                                                                // ładowanie przy PRD jest wynikiem tego, że PWM pracuje na odwrót, tj. wyjścia są zanegowane

    SetEPwmxPeriod(EPwmxRegs, GRID_FREQUENCY);                                                  // częstotliwość pracy tranzystorów IGBT dla fgrid == 50.000Hz
    EPwmxRegs->TBPHS.all = 0x00;                                                                // wartość ładowana do licznika podczas synchronizacji
    EPwmxRegs->TBCTR = 0x00;                                                                    // zerowanie licznika PWM
    EPwmxRegs->CMPA.bit.CMPA = 0x00;                                                            // zerowe wypełnienie PWM

    EPwmxRegs->TBCTL.bit.FREE_SOFT = 0b11;                                                      // sygnał aktywny w trybie debugowania
    EPwmxRegs->TBCTL.bit.PHSDIR = TB_UP;                                                        // liczy w górę przy synchronizacji
    EPwmxRegs->TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;                                             // tryb licznika up-down
    EPwmxRegs->TBCTL.bit.SYNCOSEL = TB_SYNC_IN;                                                 // wyjście synchronizacji, jest wejściem
    EPwmxRegs->TBCTL.bit.PHSEN = TB_ENABLE;                                                     // synchronizacja modułu z sygnałem SYNCI
    EPwmxRegs->TBCTL.bit.CLKDIV = TB_DIV1;
    EPwmxRegs->TBCTL.bit.HSPCLKDIV = TB_DIV1;                                                   // taktowanie TBCLK = EPWMCLK / (1 * 1)

    EPwmxRegs->AQCTLA.bit.CAU = AQ_SET;                                                         // ustaw wyjście A, gdy licznik A dojdzie do zadanej wartości oraz licznik główny liczy w górę
    EPwmxRegs->AQCTLA.bit.CAD = AQ_CLEAR;                                                       // wyzeruj wyjście A, gdy licznika A dojdzie do zadanej wartości oraz licznik główny liczy w dół

    EPwmxRegs->DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;                                             // aktywujemy moduł sterowania komplementarnego z czasem martwym
    EPwmxRegs->DBCTL.bit.POLSEL = DB_ACTV_HIC;                                                  // wyjście komplementarne B jest negacją wyjścia A, wyjścia są aktywne jako plus
    EPwmxRegs->DBCTL.bit.OUTSWAP = 0b11;                                                        // wyjście zamienione, co umożliwia ustawienie wartości wypełnienia 0 == 0% oraz PERIOD == 100%
    EPwmxRegs->DBCTL.bit.HALFCYCLE = 1;                                                         // moduł komplementarny pracuje z podwójną częstotliwością modułu PWM
    EPwmxRegs->DBFED.bit.DBFED = IGBT_FALLING_EDGE_DBFED;                                       // czas opóźnienia dla zbocza opadającego
    EPwmxRegs->DBRED.bit.DBRED = IGBT_RISING_EDGE_DBRED;                                        // czas opóźnienia dla zbocza narastającego

    EPwmxRegs->EPWMXLINK.bit.TBPRDLINK = 1;                                                     // linkujemy nastawę TBPRD z EPwm2.TBPRD

    EALLOW;
    EPwmxRegs->DCTRIPSEL.bit.DCAHCOMPSEL = 3;                                                   // wejście DCAH jako TRIPIN4 z ePWM X-BAR [konfiguracja w GPIO.c]
    EPwmxRegs->DCACTL.bit.EVT1SRCSEL = 0;                                                       // DCAEVT1 źródło bezpośrednio bez filtracji
    EPwmxRegs->DCACTL.bit.EVT1FRCSYNCSEL = 1;                                                   // DCAEVT1 źródło jest asynchroniczne

    EPwmxRegs->TZCTL.bit.TZA = TZ_FORCE_LO;                                                     // wyjście EPWMxA ma być zero jak jest aktywny TZ
    EPwmxRegs->TZCTL.bit.TZB = TZ_FORCE_LO;                                                     // wyjście EPWMxB ma być zero jak jest aktywny TZ
    EPwmxRegs->TZFRC.bit.OST = 1;                                                               // na starcie wymuszamy OST jako softwarowe wyłączenie PWMów
    EPwmxRegs->TZSEL.bit.DCAEVT1 = 1;                                                           // DCAEVT1 jako one-shot-trip
    EPwmxRegs->TZDCSEL.bit.DCAEVT1 = 2;                                                         // DCAEVT1 generujemy, gdy DCAH = 1; DCAL = X

                                                                                                // *** Konfiguracja trybu High Resolution
    EPwmxRegs->HRCNFG.bit.EDGMODE = HR_BEP;                                                     // MEP kontroluje obydwa zbocza sygnału
    EPwmxRegs->HRCNFG.bit.CTLMODE = HR_CMP;                                                     // MEP kontrolowany jest przez wypełnienie
    EPwmxRegs->HRCNFG.bit.HRLOAD = 0;                                                           // nowe wartości CMPAHR ładowane są gdy TBCTR == 0x0000
    EPwmxRegs->HRCNFG.bit.SELOUTB = 0;                                                          // negacja wyjścia B przez moduł HRPWM wyłączona
    EPwmxRegs->HRCNFG.bit.AUTOCONV = 1;                                                         // automatyczne skalowanie HRMSTEP
    EPwmxRegs->HRCNFG.bit.SWAPAB = 0;                                                           // wyjścia A i B nie są zamienione
    EPwmxRegs->HRCNFG.bit.EDGMODEB = HR_DISABLE;                                                // MEP wyłączony na CMPB

    EPwmxRegs->HRPCTL.bit.TBPHSHRLOADE = 1;                                                     // aktywowanie synchronizacji liczników up/down z sygnałem HR
    EPwmxRegs->HRPCTL.bit.HRPE = 1;                                                             // aktywowanie HRPWM
    EDIS;

Full info from CCS about this EPwm register

EPwm7Regs	struct EPWM_REGS	{TBCTL={all=57350,bit={CTRMODE=2,PHSEN=1,PRDLD=0,SYNCOSEL=0,SWFSYNC=0...}},TBCTL2=...	0x00004600@Data	
	TBCTL	union TBCTL_REG	{all=57350,bit={CTRMODE=2,PHSEN=1,PRDLD=0,SYNCOSEL=0,SWFSYNC=0...}}	0x00004600@Data	
	TBCTL2	union TBCTL2_REG	{all=0,bit={rsvd1=0,rsvd2=0,OSHTSYNCMODE=0,OSHTSYNC=0,rsvd3=0...}}	0x00004601@Data	
	rsvd1	unsigned int[2]	[0,0]	0x00004602@Data	
	TBCTR	unsigned int	1633	0x00004604@Data	
	TBSTS	union TBSTS_REG	{all=3,bit={CTRDIR=1,SYNCI=1,CTRMAX=0,rsvd1=0}}	0x00004605@Data	
	rsvd2	unsigned int[2]	[0,0]	0x00004606@Data	
	CMPCTL	union CMPCTL_REG	{all=323,bit={LOADAMODE=3,LOADBMODE=0,SHDWAMODE=0,rsvd1=0,SHDWBMODE=1...}}	0x00004608@Data	
	CMPCTL2	union CMPCTL2_REG	{all=0,bit={LOADCMODE=0,LOADDMODE=0,SHDWCMODE=0,rsvd1=0,SHDWDMODE=0...}}	0x00004609@Data	
	rsvd3	unsigned int[2]	[0,0]	0x0000460A@Data	
	DBCTL	union DBCTL_REG	{all=45067,bit={OUT_MODE=3,POLSEL=2,IN_MODE=0,LOADREDMODE=0,LOADFEDMODE=0...}}	0x0000460C@Data	
	DBCTL2	union DBCTL2_REG	{all=0,bit={LOADDBCTLMODE=0,SHDWDBCTLMODE=0,rsvd1=0}}	0x0000460D@Data	
	rsvd4	unsigned int[2]	[0,0]	0x0000460E@Data	
	AQCTL	union AQCTL_REG	{all=0,bit={LDAQAMODE=0,LDAQBMODE=0,SHDWAQAMODE=0,rsvd1=0,SHDWAQBMODE=0...}}	0x00004610@Data	
	AQTSRCSEL	union AQTSRCSEL_REG	{all=0,bit={T1SEL=0,T2SEL=0,rsvd1=0}}	0x00004611@Data	
	rsvd5	unsigned int[2]	[0,0]	0x00004612@Data	
	PCCTL	union PCCTL_REG	{all=0,bit={CHPEN=0,OSHTWTH=0,CHPFREQ=0,CHPDUTY=0,rsvd1=0}}	0x00004614@Data	
	rsvd6	unsigned int[3]	[0,0,0]	0x00004615@Data	
	VCAPCTL	union VCAPCTL_REG	{all=0,bit={VCAPE=0,VCAPSTART=0,TRIGSEL=0,rsvd1=0,VDELAYDIV=0...}}	0x00004618@Data	
	VCNTCFG	union VCNTCFG_REG	{all=0,bit={STARTEDGE=0,rsvd1=0,STARTEDGESTS=0,STOPEDGE=0,rsvd2=0...}}	0x00004619@Data	
	rsvd7	unsigned int[6]	[0,0,0,0,0...]	0x0000461A@Data	
	HRCNFG	union HRCNFG_REG	{all=64,bit={EDGMODE=0,CTLMODE=0,HRLOAD=0,SELOUTB=0,AUTOCONV=1...}}	0x00004620@Data	
	HRPWR	union HRPWR_REG	{all=0,bit={rsvd1=0,rsvd2=0,rsvd3=0,rsvd4=0,rsvd5=0...}}	0x00004621@Data	
	rsvd8	unsigned int[4]	[0,0,0,0]	0x00004622@Data	
	HRMSTEP	union HRMSTEP_REG	{all=0,bit={HRMSTEP=0,rsvd1=0}}	0x00004626@Data	
	HRCNFG2	union HRCNFG2_REG	{all=0,bit={EDGMODEDB=0,CTLMODEDBRED=0,CTLMODEDBFED=0,rsvd1=0,rsvd2=0...}}	0x00004627@Data	
	rsvd9	unsigned int[5]	[0,0,0,0,0]	0x00004628@Data	
	HRPCTL	union HRPCTL_REG	{all=5,bit={HRPE=1,PWMSYNCSEL=0,TBPHSHRLOADE=1,rsvd1=0,PWMSYNCSELX=0...}}	0x0000462D@Data	
	TRREM	union TRREM_REG	{all=256,bit={TRREM=256,rsvd1=0}}	0x0000462E@Data	
	rsvd10	unsigned int[5]	[0,0,0,0,0]	0x0000462F@Data	
	GLDCTL	union GLDCTL_REG	{all=0,bit={GLD=0,GLDMODE=0,OSHTMODE=0,rsvd1=0,GLDPRD=0...}}	0x00004634@Data	
	GLDCFG	union GLDCFG_REG	{all=0,bit={TBPRD_TBPRDHR=0,CMPA_CMPAHR=0,CMPB_CMPBHR=0,CMPC=0,CMPD=0...}}	0x00004635@Data	
	rsvd11	unsigned int[2]	[0,0]	0x00004636@Data	
	EPWMXLINK	union EPWMXLINK_REG	{all=1611032161,bit={TBPRDLINK=1,CMPALINK=6,CMPBLINK=6,CMPCLINK=6,CMPDLINK=6...}}	0x00004638@Data	
	rsvd12	unsigned int[4]	[0,0,0,1]	0x0000463A@Data	
	EPWMREV	union EPWMREV_REG	{all=1024,bit={REV=0,TYPE=4}}	0x0000463E@Data	
	rsvd13	unsigned int	768	0x0000463F@Data	
	AQCTLA	union AQCTLA_REG	{all=96,bit={ZRO=0,PRD=0,CAU=2,CAD=1,CBU=0...}}	0x00004640@Data	
	AQCTLA2	union AQCTLA2_REG	{all=0,bit={T1U=0,T1D=0,T2U=0,T2D=0,rsvd1=0}}	0x00004641@Data	
	AQCTLB	union AQCTLB_REG	{all=0,bit={ZRO=0,PRD=0,CAU=0,CAD=0,CBU=0...}}	0x00004642@Data	
	AQCTLB2	union AQCTLB2_REG	{all=0,bit={T1U=0,T1D=0,T2U=0,T2D=0,rsvd1=0}}	0x00004643@Data	
	rsvd14	unsigned int[3]	[0,0,0]	0x00004644@Data	
	AQSFRC	union AQSFRC_REG	{all=0,bit={ACTSFA=0,OTSFA=0,ACTSFB=0,OTSFB=0,RLDCSF=0...}}	0x00004647@Data	
	rsvd15	unsigned int	0	0x00004648@Data	
	AQCSFRC	union AQCSFRC_REG	{all=0,bit={CSFA=0,CSFB=0,rsvd1=0}}	0x00004649@Data	
	rsvd16	unsigned int[6]	[0,0,0,0,0...]	0x0000464A@Data	
	DBREDHR	union DBREDHR_REG	{all=0,bit={rsvd1=0,rsvd2=0,rsvd3=0,DBREDHR=0}}	0x00004650@Data	
	DBRED	union DBRED_REG	{all=239,bit={DBRED=239,rsvd1=0}}	0x00004651@Data	
	DBFEDHR	union DBFEDHR_REG	{all=0,bit={rsvd1=0,rsvd2=0,rsvd3=0,DBFEDHR=0}}	0x00004652@Data	
	DBFED	union DBFED_REG	{all=239,bit={DBFED=239,rsvd1=0}}	0x00004653@Data	
	rsvd17	unsigned int[12]	[0,0,0,0,0...]	0x00004654@Data	
	TBPHS	union TBPHS_REG	{all=0,bit={TBPHSHR=0,TBPHS=0}}	0x00004660@Data	
	TBPRDHR	unsigned int	0	0x00004662@Data	
	TBPRD	unsigned int	3888	0x00004663@Data	
	rsvd18	unsigned int[6]	[0,0,0,0,0...]	0x00004664@Data	
	CMPA	union CMPA_REG	{all=131072000,bit={CMPAHR=0,CMPA=2000}}	0x0000466A@Data	
	CMPB	union CMPB_REG	{all=0,bit={CMPBHR=0,CMPB=0}}	0x0000466C@Data	
	rsvd19	unsigned int	0	0x0000466E@Data	
	CMPC	unsigned int	0	0x0000466F@Data	
	rsvd20	unsigned int	0	0x00004670@Data	
	CMPD	unsigned int	0	0x00004671@Data	
	rsvd21	unsigned int[2]	[0,0]	0x00004672@Data	
	GLDCTL2	union GLDCTL2_REG	{all=0,bit={OSHTLD=0,GFRCLD=0,rsvd1=0}}	0x00004674@Data	
	rsvd22	unsigned int[2]	[0,0]	0x00004675@Data	
	SWVDELVAL	unsigned int	0	0x00004677@Data	
	rsvd23	unsigned int[8]	[0,0,0,0,0...]	0x00004678@Data	
	TZSEL	union TZSEL_REG	{all=16384,bit={CBC1=0,CBC2=0,CBC3=0,CBC4=0,CBC5=0...}}	0x00004680@Data	
	rsvd24	unsigned int	0	0x00004681@Data	
	TZDCSEL	union TZDCSEL_REG	{all=2,bit={DCAEVT1=2,DCAEVT2=0,DCBEVT1=0,DCBEVT2=0,rsvd1=0}}	0x00004682@Data	
	rsvd25	unsigned int	0	0x00004683@Data	
	TZCTL	union TZCTL_REG	{all=10,bit={TZA=2,TZB=2,DCAEVT1=0,DCAEVT2=0,DCBEVT1=0...}}	0x00004684@Data	
	TZCTL2	union TZCTL2_REG	{all=0,bit={TZAU=0,TZAD=0,TZBU=0,TZBD=0,rsvd1=0...}}	0x00004685@Data	
	TZCTLDCA	union TZCTLDCA_REG	{all=0,bit={DCAEVT1U=0,DCAEVT1D=0,DCAEVT2U=0,DCAEVT2D=0,rsvd1=0}}	0x00004686@Data	
	TZCTLDCB	union TZCTLDCB_REG	{all=0,bit={DCBEVT1U=0,DCBEVT1D=0,DCBEVT2U=0,DCBEVT2D=0,rsvd1=0}}	0x00004687@Data	
	rsvd26	unsigned int[5]	[0,0,0,0,0]	0x00004688@Data	
	TZEINT	union TZEINT_REG	{all=0,bit={rsvd1=0,CBC=0,OST=0,DCAEVT1=0,DCAEVT2=0...}}	0x0000468D@Data	
	rsvd27	unsigned int[5]	[0,0,0,0,0]	0x0000468E@Data	
	TZFLG	union TZFLG_REG	{all=0,bit={INT=0,CBC=0,OST=0,DCAEVT1=0,DCAEVT2=0...}}	0x00004693@Data	
	TZCBCFLG	union TZCBCFLG_REG	{all=0,bit={CBC1=0,CBC2=0,CBC3=0,CBC4=0,CBC5=0...}}	0x00004694@Data	
	TZOSTFLG	union TZOSTFLG_REG	{all=64,bit={OST1=0,OST2=0,OST3=0,OST4=0,OST5=0...}}	0x00004695@Data	
	rsvd28	unsigned int	0	0x00004696@Data	
	TZCLR	union TZCLR_REG	{all=0,bit={INT=0,CBC=0,OST=0,DCAEVT1=0,DCAEVT2=0...}}	0x00004697@Data	
	TZCBCCLR	union TZCBCCLR_REG	{all=0,bit={CBC1=0,CBC2=0,CBC3=0,CBC4=0,CBC5=0...}}	0x00004698@Data	
	TZOSTCLR	union TZOSTCLR_REG	{all=0,bit={OST1=0,OST2=0,OST3=0,OST4=0,OST5=0...}}	0x00004699@Data	
	rsvd29	unsigned int	0	0x0000469A@Data	
	TZFRC	union TZFRC_REG	{all=0,bit={rsvd1=0,CBC=0,OST=0,DCAEVT1=0,DCAEVT2=0...}}	0x0000469B@Data	
	rsvd30	unsigned int[8]	[0,0,0,0,0...]	0x0000469C@Data	
	ETSEL	union ETSEL_REG	{all=0,bit={INTSEL=0,INTEN=0,SOCASELCMP=0,SOCBSELCMP=0,INTSELCMP=0...}}	0x000046A4@Data	
	rsvd31	unsigned int	0	0x000046A5@Data	
	ETPS	union ETPS_REG	{all=0,bit={INTPRD=0,INTCNT=0,INTPSSEL=0,SOCPSSEL=0,rsvd1=0...}}	0x000046A6@Data	
	rsvd32	unsigned int	0	0x000046A7@Data	
	ETFLG	union ETFLG_REG	{all=0,bit={INT=0,rsvd1=0,SOCA=0,SOCB=0,rsvd2=0}}	0x000046A8@Data	
	rsvd33	unsigned int	0	0x000046A9@Data	
	ETCLR	union ETCLR_REG	{all=0,bit={INT=0,rsvd1=0,SOCA=0,SOCB=0,rsvd2=0}}	0x000046AA@Data	
	rsvd34	unsigned int	0	0x000046AB@Data	
	ETFRC	union ETFRC_REG	{all=0,bit={INT=0,rsvd1=0,SOCA=0,SOCB=0,rsvd2=0}}	0x000046AC@Data	
	rsvd35	unsigned int	0	0x000046AD@Data	
	ETINTPS	union ETINTPS_REG	{all=0,bit={INTPRD2=0,INTCNT2=0,rsvd1=0}}	0x000046AE@Data	
	rsvd36	unsigned int	0	0x000046AF@Data	
	ETSOCPS	union ETSOCPS_REG	{all=0,bit={SOCAPRD2=0,SOCACNT2=0,SOCBPRD2=0,SOCBCNT2=0}}	0x000046B0@Data	
	rsvd37	unsigned int	0	0x000046B1@Data	
	ETCNTINITCTL	union ETCNTINITCTL_REG	{all=0,bit={rsvd1=0,INTINITFRC=0,SOCAINITFRC=0,SOCBINITFRC=0,INTINITEN=0...}}	0x000046B2@Data	
	rsvd38	unsigned int	0	0x000046B3@Data	
	ETCNTINIT	union ETCNTINIT_REG	{all=0,bit={INTINIT=0,SOCAINIT=0,SOCBINIT=0,rsvd1=0}}	0x000046B4@Data	
	rsvd39	unsigned int[11]	[0,0,0,0,0...]	0x000046B5@Data	
	DCTRIPSEL	union DCTRIPSEL_REG	{all=3,bit={DCAHCOMPSEL=3,DCALCOMPSEL=0,DCBHCOMPSEL=0,DCBLCOMPSEL=0}}	0x000046C0@Data	
	rsvd40	unsigned int[2]	[0,0]	0x000046C1@Data	
	DCACTL	union DCACTL_REG	{all=2,bit={EVT1SRCSEL=0,EVT1FRCSYNCSEL=1,EVT1SOCE=0,EVT1SYNCE=0,rsvd1=0...}}	0x000046C3@Data	
	DCBCTL	union DCBCTL_REG	{all=0,bit={EVT1SRCSEL=0,EVT1FRCSYNCSEL=0,EVT1SOCE=0,EVT1SYNCE=0,rsvd1=0...}}	0x000046C4@Data	
	rsvd41	unsigned int[2]	[0,0]	0x000046C5@Data	
	DCFCTL	union DCFCTL_REG	{all=0,bit={SRCSEL=0,BLANKE=0,BLANKINV=0,PULSESEL=0,EDGEFILTSEL=0...}}	0x000046C7@Data	
	DCCAPCTL	union DCCAPCTL_REG	{all=0,bit={CAPE=0,SHDWMODE=0,rsvd1=0,CAPSTS=0,CAPCLR=0...}}	0x000046C8@Data	
	DCFOFFSET	unsigned int	0	0x000046C9@Data	
	DCFOFFSETCNT	unsigned int	0	0x000046CA@Data	
	DCFWINDOW	unsigned int	0	0x000046CB@Data	
	DCFWINDOWCNT	unsigned int	0	0x000046CC@Data	
	rsvd42	unsigned int[2]	[0,0]	0x000046CD@Data	
	DCCAP	unsigned int	0	0x000046CF@Data	
	rsvd43	unsigned int[2]	[0,0]	0x000046D0@Data	
	DCAHTRIPSEL	union DCAHTRIPSEL_REG	{all=0,bit={TRIPINPUT1=0,TRIPINPUT2=0,TRIPINPUT3=0,TRIPINPUT4=0,TRIPINPUT5=0...}}	0x000046D2@Data	
	DCALTRIPSEL	union DCALTRIPSEL_REG	{all=0,bit={TRIPINPUT1=0,TRIPINPUT2=0,TRIPINPUT3=0,TRIPINPUT4=0,TRIPINPUT5=0...}}	0x000046D3@Data	
	DCBHTRIPSEL	union DCBHTRIPSEL_REG	{all=0,bit={TRIPINPUT1=0,TRIPINPUT2=0,TRIPINPUT3=0,TRIPINPUT4=0,TRIPINPUT5=0...}}	0x000046D4@Data	
	DCBLTRIPSEL	union DCBLTRIPSEL_REG	{all=0,bit={TRIPINPUT1=0,TRIPINPUT2=0,TRIPINPUT3=0,TRIPINPUT4=0,TRIPINPUT5=0...}}	0x000046D5@Data	
	rsvd44	unsigned int[39]	[0,0,0,0,0...]	0x000046D6@Data	
	HWVDELVAL	unsigned int	0	0x000046FD@Data	
	VCNTVAL	unsigned int	0	0x000046FE@Data	
	rsvd45	unsigned int	0	0x000046FF@Data	

  • I'll get back to you. I'm gonna dissect your code and see what the issue is.
  • It seems to be problem with HRPWM. When I set bit HRPCTL.HRPE to 0 all come back to normal, but when enabled HRPE it makes weird things.

    Another weird thing: self-changing CMPA value from 1500 to 1501 and again from 1501 to 1500 without possibility to change it by hand :)

    So - i'm still looking for error.

  • OK, so there is more information:

    I have main EPwm1 that is used to clock two ADC converters on channel EPWM1A and EPWM1B. EPwm1 register is working with two times of frequency of EPwm2, 3, 4, 6, 7 and 8 (named as EPwmSET). This 6 PWMs are for three-level three phase IGBTs.

    I was able to properly synchronize EPwmSET with EPwm1 only when I disable HRPWM on EPwmSET (bit HRPCTL.HRPE == 0). Unofrtunetly I also disabled CMPAHR/TBPRDHR registry settings. I used workaround - EPwmSET is synchronized with EPwm1 using OSHTSYNC. Also EPwmSET must be phase corrected with EPwm1 so I'm using OSHTSYNC with CMPC EPWM1 register.

    This is my full setup:

    // ADC EPwm1 setup:
        ADCClockRegs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;                                              // tryb shadow na rejestry CMPA
        ADCClockRegs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;                                              // tryb shadow na rejestry CMPB
        ADCClockRegs.CMPCTL2.bit.SHDWCMODE = CC_SHADOW;                                             // tryb shadow na rejestry CMPC
    
        SetADCClockPeriod(GRID_FREQUENCY);                                                          // częstotliwość pracy przetwornika ADC dla fgrid == 50.000Hz
        ADCClockRegs.TBPHS.all = 0x00;                                                              // przesunięcie fazowe wyłączone
        ADCClockRegs.TBCTR = 0x00;                                                                  // zerowanie licznika PWM
    
        ADCClockRegs.TBCTL.bit.PRDLD = 0;                                                           // rejestr TBPRD jest ładowany gdy TBCTR == 0x0000
        ADCClockRegs.TBCTL.bit.FREE_SOFT = 0b11;                                                    // sygnał aktywny w trybie debugowania
        ADCClockRegs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;                                           // tryb licznika up-down
        ADCClockRegs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;                                          // wyjście synchronizacji, gdy licznik będzie mieć wartość CMPC
        ADCClockRegs.TBCTL.bit.PHSEN = TB_DISABLE;                                                  // wejście synchronizacji wyłączone
        ADCClockRegs.TBCTL.bit.CLKDIV = TB_DIV1;                                                    // taktowanie TBCLK = EPWMCLK / (1 * 1)
        ADCClockRegs.TBCTL.bit.HSPCLKDIV = TB_DIV1;                                                 // taktowanie TBCLK = EPWMCLK / (1 * 1)
    
        ADCClockRegs.TBCTL2.bit.OSHTSYNCMODE = 1;                                                   // aktywowanie trybu pojedynczej synchronizacji
        ADCClockRegs.TBCTL2.bit.SYNCOSELX = 1;                                                      // wyjście synchronizacji, gdy licznik będzie mieć wartość CMPC
    
        ADCClockRegs.AQCTLA.bit.CAU = AQ_SET;                                                       // ustaw wyjście gdy licznik dojdzie do CMPA jak liczy w górę
        ADCClockRegs.AQCTLA.bit.CAD = AQ_CLEAR;                                                     // zeruj wyjście gdy licznik dojdzie do CMPA jak liczy w dół
        ADCClockRegs.AQCTLA.bit.PRD = AQ_NO_ACTION;                                                 // brak reakcji gdy licznik dojdzie do PERIOD
        ADCClockRegs.AQCTLA.bit.ZRO = AQ_NO_ACTION;                                                 // brak reakcji gdy licznik dojdzie do zera
        ADCClockRegs.AQCTLB.bit.CAU = AQ_SET;                                                       // ustaw wyjście gdy licznik dojdzie do CMPB jak liczy w górę
        ADCClockRegs.AQCTLB.bit.CAD = AQ_CLEAR;                                                     // zeruj wyjście gdy licznik dojdzie do CMPB jak liczy w dół
        ADCClockRegs.AQCTLB.bit.PRD = AQ_NO_ACTION;                                                 // brak reakcji gdy licznik dojdzie do PERIOD
        ADCClockRegs.AQCTLB.bit.ZRO = AQ_NO_ACTION;                                                 // brak reakcji gdy licznik dojdzie do zera
    
        ADCClockRegs.ETSEL.bit.INTSEL = ET_CTRU_CMPA;                                               // przerwanie INT generowane gdy licznik dojdzie do CMPA licząc w górę
        EPwm1Regs_ETSEL_Shadow = ADCClockRegs.ETSEL.all;                                            // kopiowanie ETSEL dla CPU2
        ADCClockRegs.ETPS.bit.INTPSSEL = 0;
        ADCClockRegs.ETPS.bit.INTPRD = 1;                                                           // przerwanie co każdy event
    
        // Funkcjonalność wyłączenia softwarowego sygnału taktującego jest realizowane przez TripZone 6.
        // Procesor ustawiając programowy TZ6 wyłącza generowanie sygnału taktującego przetworniki ADC.
        EALLOW;
        ADCClockRegs.TZCTL.bit.TZA = TZ_FORCE_LO;                                                   // wyjście EPWM1A ma być zero jak jest aktywny TZ
        ADCClockRegs.TZCTL.bit.TZB = TZ_FORCE_LO;                                                   // wyjście EPWM1B ma być zero jak jest aktywny TZ
        ADCClockRegs.TZFRC.bit.OST = 1;                                                             // przy konfiguracji wymuszamy już TripZone
    
        // Konfiguracja trybu High Resolution
        ADCClockRegs.HRCNFG.bit.EDGMODE = HR_BEP;                                                   // MEP kontroluje obydwa zbocza sygnału
        ADCClockRegs.HRCNFG.bit.CTLMODE = HR_CMP;                                                   // MEP kontrolowany jest przez wypełnienie
        ADCClockRegs.HRCNFG.bit.HRLOAD = 0;                                                         // nowe wartości CMPAHR ładowane są gdy TBCTR == 0x0000
        ADCClockRegs.HRCNFG.bit.SELOUTB = 0;                                                        // wyjście B jest zwykłym wyjściem PWM
        ADCClockRegs.HRCNFG.bit.AUTOCONV = 1;                                                       // automatyczne skalowanie HRMSTEP
        ADCClockRegs.HRCNFG.bit.SWAPAB = 0;                                                         // wyjścia A i B nie są zamienione
        ADCClockRegs.HRCNFG.bit.EDGMODEB = HR_BEP;                                                  // MEP kontroluje obydwa zbocza sygnału na wyjściu B
        ADCClockRegs.HRCNFG.bit.CTLMODEB = HR_CMP;                                                  // MEP kontrolowany jest przez wypełnienie na wyjściu B
        ADCClockRegs.HRCNFG.bit.HRLOADB = 0;                                                        // nowe wartości CMPBHR ładowane są gdy TBCTR == 0x0000
    
        //ADCClockRegs.HRPCTL.bit.TBPHSHRLOADE = 1;                                                   // aktywowanie synchronizacji liczników up/down z sygnałem HR
        ADCClockRegs.HRPCTL.bit.HRPE = 1;                                                           // aktywowanie HRPWM
        EDIS;
    
    // IGBT Setup:
    void InitializeEPwmxRegs(volatile struct EPWM_REGS* EPwmxRegs)
    {
        // TODO: ustawienie trip zone
        // Najpierw należy zmienić tryb Shadow Mode, bo zmiana podowuje wyzerowanie rejestrów CMPA oraz CMPB
        EPwmxRegs->CMPCTL.bit.SHDWAMODE = CC_SHADOW;                                                // tryb shadow dla rejestrów EPWMxA jest aktywny
        EPwmxRegs->CMPCTL.bit.SHDWBMODE = CC_SHADOW;                                                // tryb shadow dla rejestrów EPWMxB jest aktywny
        EPwmxRegs->CMPCTL.bit.LOADAMODE = CC_CTR_PRD;                                               // nowa wartość wypełnienia A będzie ładowana, gdy główny licznik będzie równy PRD
        EPwmxRegs->CMPCTL.bit.LOADBMODE = CC_CTR_PRD;                                               // nowa wartość wypełnienia B będzie ładowana, gdy główny licznik będzie równy PRD
                                                                                                    // ładowanie przy PRD jest wynikiem tego, że PWM pracuje na odwrót, tj. wyjścia są zanegowane
    
        SetEPwmxPeriod(EPwmxRegs, GRID_FREQUENCY);                                                  // częstotliwość pracy tranzystorów IGBT dla fgrid == 50.000Hz
        EPwmxRegs->TBPHS.all = 0x00;                                                                // wartość ładowana do licznika podczas synchronizacji
        EPwmxRegs->TBCTR = 0x00;                                                                    // zerowanie licznika PWM
        EPwmxRegs->CMPA.bit.CMPA = 0x00;                                                            // zerowe wypełnienie PWM
    
        EPwmxRegs->TBCTL.bit.FREE_SOFT = 0b11;                                                      // sygnał aktywny w trybie debugowania
        EPwmxRegs->TBCTL.bit.PHSDIR = TB_UP;                                                        // liczy w górę przy synchronizacji
        EPwmxRegs->TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;                                             // tryb licznika up-down
        EPwmxRegs->TBCTL.bit.SYNCOSEL = TB_SYNC_IN;                                                 // wyjście synchronizacji, jest wejściem
        EPwmxRegs->TBCTL.bit.PHSEN = TB_ENABLE;                                                     // synchronizacja modułu z sygnałem SYNCI
        EPwmxRegs->TBCTL.bit.CLKDIV = TB_DIV1;
        EPwmxRegs->TBCTL.bit.HSPCLKDIV = TB_DIV1;                                                   // taktowanie TBCLK = EPWMCLK / (1 * 1)
    
        EPwmxRegs->AQCTLA.bit.CAU = AQ_SET;                                                         // ustaw wyjście A, gdy licznik A dojdzie do zadanej wartości oraz licznik główny liczy w górę
        EPwmxRegs->AQCTLA.bit.CAD = AQ_CLEAR;                                                       // wyzeruj wyjście A, gdy licznika A dojdzie do zadanej wartości oraz licznik główny liczy w dół
    
        EPwmxRegs->DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;                                             // aktywujemy moduł sterowania komplementarnego z czasem martwym
        EPwmxRegs->DBCTL.bit.POLSEL = DB_ACTV_HIC;                                                  // wyjście komplementarne B jest negacją wyjścia A, wyjścia są aktywne jako plus
        EPwmxRegs->DBCTL.bit.OUTSWAP = 0b11;                                                        // wyjście zamienione, co umożliwia ustawienie wartości wypełnienia 0 == 0% oraz PERIOD == 100%
        EPwmxRegs->DBCTL.bit.HALFCYCLE = 1;                                                         // moduł komplementarny pracuje z podwójną częstotliwością modułu PWM
        EPwmxRegs->DBFED.bit.DBFED = IGBT_FALLING_EDGE_DBFED;                                       // czas opóźnienia dla zbocza opadającego
        EPwmxRegs->DBRED.bit.DBRED = IGBT_RISING_EDGE_DBRED;                                        // czas opóźnienia dla zbocza narastającego
    
        EPwmxRegs->EPWMXLINK.bit.TBPRDLINK = 1;                                                     // linkujemy nastawę TBPRD z EPwm2.TBPRD
    
        EALLOW;
        EPwmxRegs->DCTRIPSEL.bit.DCAHCOMPSEL = 3;                                                   // wejście DCAH jako TRIPIN4 z ePWM X-BAR [konfiguracja w GPIO.c]
        EPwmxRegs->DCACTL.bit.EVT1SRCSEL = 0;                                                       // DCAEVT1 źródło bezpośrednio bez filtracji
        EPwmxRegs->DCACTL.bit.EVT1FRCSYNCSEL = 1;                                                   // DCAEVT1 źródło jest asynchroniczne
    
        EPwmxRegs->TZCTL.bit.TZA = TZ_FORCE_LO;                                                     // wyjście EPWMxA ma być zero jak jest aktywny TZ
        EPwmxRegs->TZCTL.bit.TZB = TZ_FORCE_LO;                                                     // wyjście EPWMxB ma być zero jak jest aktywny TZ
        EPwmxRegs->TZFRC.bit.OST = 1;                                                               // na starcie wymuszamy OST jako softwarowe wyłączenie PWMów
        EPwmxRegs->TZSEL.bit.DCAEVT1 = 1;                                                           // DCAEVT1 jako one-shot-trip
        EPwmxRegs->TZDCSEL.bit.DCAEVT1 = 2;                                                         // DCAEVT1 generujemy, gdy DCAH = 1; DCAL = X
    
                                                                                                    // *** Konfiguracja trybu High Resolution
        EPwmxRegs->HRCNFG.bit.EDGMODE = HR_BEP;                                                     // MEP kontroluje obydwa zbocza sygnału
        EPwmxRegs->HRCNFG.bit.CTLMODE = HR_CMP;                                                     // MEP kontrolowany jest przez wypełnienie
        EPwmxRegs->HRCNFG.bit.HRLOAD = 0;                                                           // nowe wartości CMPAHR ładowane są gdy TBCTR == 0x0000
        EPwmxRegs->HRCNFG.bit.SELOUTB = 0;                                                          // negacja wyjścia B przez moduł HRPWM wyłączona
        EPwmxRegs->HRCNFG.bit.AUTOCONV = 1;                                                         // automatyczne skalowanie HRMSTEP
        EPwmxRegs->HRCNFG.bit.SWAPAB = 0;                                                           // wyjścia A i B nie są zamienione
        EPwmxRegs->HRCNFG.bit.EDGMODEB = HR_DISABLE;                                                // MEP wyłączony na CMPB
    
        EPwmxRegs->HRPCTL.bit.TBPHSHRLOADE = 1;                                                     // aktywowanie synchronizacji liczników up/down z sygnałem HR
        EPwmxRegs->HRPCTL.bit.HRPE = 0;                                                             // deaktywowanie HRPWM (jakiś problem w procku??)
        EDIS;
    }
    
    //╔════════════════════════════════════════════════════════════════════════════════════════════╗
    //║  PUBLICZNE FUNKCJE I PROCEDURY                                                             ║
    //╚════════════════════════════════════════════════════════════════════════════════════════════╝
    void SetupIGBTModule()
    {
        /*** Konfigurujemy synchronizację PWMów ***/
        SyncSocRegs.SYNCSELECT.bit.EPWM4SYNCIN = 0;                                                 // Synchronizujemy z EPWM1SYNCOUT
        SyncSocRegs.SYNCSELECT.bit.EPWM7SYNCIN = 0;                                                 // Synchronizujemy z EPWM1SYNCOUT
        SyncSocRegs.SYNCSOCLOCK.bit.SYNCSELECT = 1;                                                 // Blokujemy rejestr SYNCSELECT
    
        // Moduł ePWM generuje sygnały tranzystorów wyjściowych (po prawej stronie aktualny stan na PCB ze względu na błąd w ścieżkach):
        //  GPWM14 = ePWM2A = U:UDC0 = !GPWM12      | GPWM14 = ePWM2A = U:UDC0 = !GPWM12
        //  GPWM12 = ePWM2B = U:UDC-                | GPWM13 = ePWM2B = U:UDC0 = !GPWM11
        //  GPWM22 = ePWM3A = V:UDC-                | GPWM22
        //  GPWM24 = ePWM3B = V:UDC0 = !GPWM22      | GPWM24
        //  GPWM32 = ePWM4A = W:UDC-                | GPWM32
        //  GPWM34 = ePWM4B = W:UDC0 = !GPWM32      | GPWM34
        //  GPWM13 = ePWM6A = U:UDC0 = !GPWM11      | GPWM12 = ePWM6A = U:UDC-
        //  GPWM11 = ePWM6B = U:UDC+                | GPWM11 = ePWM6B = U:UDC+
        //  GPWM21 = ePWM7A = V:UDC+                | GPWM21
        //  GPWM23 = ePWM7B = V:UDC0 = !GPWM21      | GPWM23
        //  GPWM31 = ePWM8A = W:UDC+                | GPWM31
        //  GPWM33 = ePWM8B = W:UDC0 = !GPWM31      | GPWM33
        InitializeEPwmxRegs(&EPwm2Regs);
        InitializeEPwmxRegs(&EPwm3Regs);
        InitializeEPwmxRegs(&EPwm4Regs);
        InitializeEPwmxRegs(&EPwm6Regs);
        InitializeEPwmxRegs(&EPwm7Regs);
        InitializeEPwmxRegs(&EPwm8Regs);
    
        /*** ustawienia PIE dla TripZone ***/
        PieCtrlRegs.PIEIFR2.bit.INTx2 = 0;                                                          // zerowanie ewentualnie oznaczonego przerwania INT2.2
        PieCtrlRegs.PIEIER2.bit.INTx2 = 1;                                                          // aktywowanie przerwania INT2.2 = EPWM2_TZ
        IER |= M_INT2;                                                                              // aktywacja grupy INT2.x
    }
    
    

    Also time diagram of PWM setup (blue lines are: lowest is EPwm1, very light two big triangles are EPwmSET, one big triangle is EPwmSET after inversion only for easy use):

    Screens from analyzer:

    1. HRPE is OFF. On I11.03.1 you see pulse - this pulse is wrtie new CMPA value and after two CONV U pulses CMPA value is restored back by program (PWM1 and PWM2 data). So on this - one pulse shot test is valid.

    2. HRPE is ON - there is only change. You see that update of CMPA value is not on CC_CTR_PRD but on CC_CTR_ZERO and eventually I have not one pulse but two with half of duty - so this is terrible for me.

  • Lukas,

    Try loading on both CTR=0 and CTR=PRD for the high resolution mode. Let me know what comes out for the signals.
  • Hi,

    yes already I found same solution - when HRPWM is enabled you don't have ability to control when to load values from shadow registers, because controlling of this takes HRCNFG.HRLOAD bits and this bist must be configured same as EDGMODE - and only with this configuration HRPWM works correctly. This is little confusing and description of HRPWM in datasheet isn;t clear about some nuances.

    Also second nuance that I found not related to HRPWM - when trip zone set outputs to low, action qualifier output pin state isn't changed. So for example - when we have output set to HI, TZ sets output to LO and we clear TZ - output sets immediate to HI. Afcourse you can set what to do with outputs if TZ occurs in AQ module, but this nuance isn't clear elaborated in datasheet.

    I suggest to add this three small tips (HRLOAD control overtake; EDGMODE must be same as HRLOAD; TZ dont change AQ output) in descriptions of ePWM and HRPWM.