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.
I'm trying to have two blocks of 3 PWMs each. The first 3 should be synchronized to each other while the other 3 should be shifted by a half period. For this purpose I decided to manipulate the PWM_INIT_MACRO() from the example PM_Sensorless.
The 3d ePWM from the first block should generate a synchronization event when it reaches the Period-Value (in Up-Down count mode). At this point, the following PWMs load 0 to their counter and will be delayed by 180°.
But right after execution of the PWM_INIT_MACRO() both SYNCOSEL and PHSEN are 0, so the changes are not applied and the code doesn't work. If I apply the changes manually in debug mode, it works. Why are the values not applied to the registers, or are there any other write-commands that cause a reset of the register?
The Code I use is here below, it's almost identical to the example code:
#define PWM_INIT_MACRO(m) \
/* Setup Sync*/ \
m->PwmARegs->TBCTL.bit.SYNCOSEL = 0; /* Pass through sync-signal to next ePWM*/ \
m->PwmBRegs->TBCTL.bit.SYNCOSEL = 0; /* Pass through sync-signal to next ePWM*/ \
m->PwmCRegs->TBCTL.bit.SYNCOSEL = 2; /* Sync-Event for next ePWM at Counter = Period. Following ePWMs will have 50% Phase delay */ \
\
/* Allow each timer to be sync'ed*/ \
m->PwmARegs->TBCTL.bit.PHSEN = 1; /*Enable Phase Load */ \
m->PwmBRegs->TBCTL.bit.PHSEN = 1; \
m->PwmCRegs->TBCTL.bit.PHSEN = 1; \
\
/* Init Timer-Base Period Register for EPWM1-EPWM3*/ \
m->PwmARegs->TBPRD = m->pwm.PeriodMax; \
m->PwmBRegs->TBPRD = m->pwm.PeriodMax; \
m->PwmCRegs->TBPRD = m->pwm.PeriodMax; \
\
/* Init Timer-Base Phase Register for EPWM1-EPWM3 (Value loaded to Counter on Sync-Event)*/ \
m->PwmARegs->TBPHS.half.TBPHS = 0; \
m->PwmBRegs->TBPHS.half.TBPHS = 0; \
m->PwmCRegs->TBPHS.half.TBPHS = 0; \
\
/* Init Timer-Base Control Register for EPWM1-EPWM3*/ \
m->PwmARegs->TBCTL.all = PWM_INIT_STATE; /* Count Up-Down, After Sync start with up Count,... */ \
m->PwmBRegs->TBCTL.all = PWM_INIT_STATE; \
m->PwmCRegs->TBCTL.all = PWM_INIT_STATE; \
\
/* Init Compare Control Register for EPWM1-EPWM3*/ \
m->PwmARegs->CMPCTL.all = CMPCTL_INIT_STATE; /*Load from Shadowed Registers when Counter is at 0*/ \
m->PwmBRegs->CMPCTL.all = CMPCTL_INIT_STATE; \
m->PwmCRegs->CMPCTL.all = CMPCTL_INIT_STATE; \
\
/* Init Action Qualifier Output A Register for EPWM1-EPWM3*/ \
m->PwmARegs->AQCTLA.all = AQCTLA_INIT_STATE; /* SET when counting Up, CLEAR when counting down*/ \
m->PwmBRegs->AQCTLA.all = AQCTLA_INIT_STATE; \
m->PwmCRegs->AQCTLA.all = AQCTLA_INIT_STATE; \
\
/* Init Dead-Band Generator Control Register for EPWM1-EPWM3*/ \
m->PwmARegs->DBCTL.all = DBCTL_INIT_STATE; /* Enable Dead-Band Module, Dead-Band (both signals low during this time) */ \
m->PwmBRegs->DBCTL.all = DBCTL_INIT_STATE; \
m->PwmCRegs->DBCTL.all = DBCTL_INIT_STATE; \
\
/* Init Dead-Band Generator for EPWM1-EPWM3*/ \
m->PwmARegs->DBFED = DBCNT_INIT_STATE; /* Set number of delay-counts between switching edges */ \
m->PwmARegs->DBRED = DBCNT_INIT_STATE; \
m->PwmBRegs->DBFED = DBCNT_INIT_STATE; \
m->PwmBRegs->DBRED = DBCNT_INIT_STATE; \
m->PwmCRegs->DBFED = DBCNT_INIT_STATE; \
m->PwmCRegs->DBRED = DBCNT_INIT_STATE; \
\
/* Init PWM Chopper Control Register for EPWM1-EPWM3*/ \
m->PwmARegs->PCCTL.all = PCCTL_INIT_STATE; /* No PWM-Chopping*/ \
m->PwmBRegs->PCCTL.all = PCCTL_INIT_STATE; \
m->PwmCRegs->PCCTL.all = PCCTL_INIT_STATE; \
\
EALLOW; /* Enable EALLOW */ \
\
/* Init Trip Zone Select Register*/ \
m->PwmARegs->TZSEL.all = TZSEL_INIT_STATE; \
m->PwmBRegs->TZSEL.all = TZSEL_INIT_STATE; \
m->PwmCRegs->TZSEL.all = TZSEL_INIT_STATE; \
\
/* Init Trip Zone Control Register*/ \
m->PwmARegs->TZCTL.all = TZCTL_INIT_STATE; \
m->PwmBRegs->TZCTL.all = TZCTL_INIT_STATE; \
m->PwmCRegs->TZCTL.all = TZCTL_INIT_STATE; \
\
EDIS; /* Disable EALLOW*/
Hello Frau Haggenmacher,
Thoughts:
1) make sure you do a Rebuild All. Sometimes the IDE is not completely competent when the header files changes (and the header file contains macroed source code).
2) Make sure that m is defined as the PWMs you wish to edit. Is any of the code in your edited file correctly writing registers?
3) May be a bad comment, but you may also want to double-check that CCS is looking at your edited version vs the library version.
===
Aside: I would recommend having the first PWM be the master PWM and then all other PWMs synch to it - the other two (in your first group of three) having no offset; the other set of three with a 180degree offset.
Thank you,
Brett
Hi,
I finally implemented the PWM-Groups with 180° phase delay, but it cost me some time since the behavior wasn't as expected.
First I tried to pass through the SYNC signal to all ePWM Modules (SYNCOSEL = 0) and synchronize them all by writing a ePWM1.TBCTL.bit.SWSYNC = 1. The first group of PWM had to load 0 into the counter while the second group had to load the same value as in the TBPRD register, resulting in a 180° phase shift. But this did not work: the phase shift was not 180° and even worse, it changed every time I triggered SWSYNC ! I even tried to Synchronize all the clocks by deactivating and re-activating TBCLKSYNC, with no effect at all.
What I found out as a working solution is to synchronize all the PWMs from the first group to TBCTR = 0 (SYNCOSEL = 1) and to pass through the sync-signal in the second group (SYNCOSEL = 0). The value in TBPHS remains 0 for the first ones and TBPRD for the latter.
The Scope image shows now that both the PWMs and the ISR that are triggered by the PWM have 180° phase shift. Signals 1 and 3 show the signal of ePWM1 and ePWM4. Signal 2 and 4 show the duration of the execution of the ISR which is triggered at TBCTR = 0 of ePWM1 or ePWM4 respectively (ISR starts in the middle of the LOW-time of the pwm, at the same time the ADC is also triggered, current in phase A & B is measured).
Hello Herr Haggenmacher,
Glad you were able to figure it out!
As you likely found, Figure 3-5 and Figure 3-7 in the current F2806x TRM are often helpful for comprehending ePWM synchronization.
Thank you,
Brett