Other Parts Discussed in Thread: C2000WARE
Tool/software: Code Composer Studio
Hello,
I'm currently trying to configure a PWM for a 3-phase inverter with adjustable high resolution frequency (arround 1MHz), dead time and a fixed duty cycle of 50%.
My first idea was to use both HR period and HR phase shift to obtain an accurate frequency with the +/-120° phase shift that is mandatory for the application but it looks like those 2 modes are not compatible. So instead I'm using the CMP/CMPHR registers.
My first attempts were with a 200MHz systclock but apparently the intOsc2 should not be used beyond 194MHz so I have been using a 100MHz frequency with a /1 EPWMCLKDIV which worked for the normal PWM but not for the HR (apparently there is an issue when the CLKDIV is not set to /2). So now my system is configured with a 180MHz SYSCLK and a 90MHz PWMCLK/TBCLK (so 1 TBCLK is 11ns).
Nonetheless I am not able to sychronise EPWM1/EPWM2 and EPWM3. EPWM1 and 2 are perfectly aligned but there is a 3.2ns delay for EPWM3 (I can't figure from where it comes as few MEP should be less than that and 1 TBCLK is more). I followed the technical manual p1967 (15.14.1.5.4.1) which says:
6. For TBPHS:TBPHSHR synchronization with high-resolution period, set both
HRPCTL[TBPSHRLOADE] = 1 and TBCTL[PHSEN] = 1. In up-down count mode these bits must be
set to 1 regardless of the contents of TBPHSHR.
I don't really understand if this is mandatory when the Phase shifting module is not used. Anyway, It doesn't change anything on my sync problem (I reconfigure the input5 xbar so that PWM1 doesn't send to much synch pulse). Also, should we send the software sync pulse before or after reenabling TBCLK ? In my opinion we should send the pulse before so that all the PWM are synchronised without possibilities of propagation latency.
So as long as It appears I can't use the phase shift synchronisation tactic, I believe that the software sync pulse would not be usefull. My only remaining strategie is to force the counters to 0 and then start the clocks and hope the PWM will always remain synchronised even when I change the period ? Furthermore It is written that the software pulse would introduce jitter. But the 3,2ns lag remains...
Here is my configuration:
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the EPWM
InputXbarRegs.INPUT5SELECT=22; //Le GPIO 22 est connecte sur extsyncin1 plutot que la P0
EDIS;
for(j=1; j<PWM_CH; j++)
{
(*ePWM[j]).TBCTL.bit.PRDLD = TB_SHADOW; // set Shadow load
(*ePWM[j]).TBPRD = period; // PWM frequency = 1/(2*TBPRD)
(*ePWM[j]).CMPB.all |= 1;
(*ePWM[j]).TBPHS.all = 0;
(*ePWM[j]).TBCTR = 0;
(*ePWM[j]).TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Select up-down
// count mode
(*ePWM[j]).TBCTL.bit.SYNCOSEL = TB_SYNC_IN; //TB_SYNC_DISABLE;
(*ePWM[j]).TBCTL.bit.HSPCLKDIV = TB_DIV1;
(*ePWM[j]).TBCTL.bit.CLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT
(*ePWM[j]).TBCTL.bit.FREE_SOFT = 11;
(*ePWM[j]).CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // LOAD CMPA on CTR = 0
(*ePWM[j]).CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
(*ePWM[j]).CMPCTL.bit.SHDWAMODE = CC_SHADOW;
(*ePWM[j]).CMPCTL.bit.SHDWBMODE = CC_SHADOW;
definirCommutation(j, (float) period);
EALLOW;
(*ePWM[j]).HRCNFG.all = 0x0;
(*ePWM[j]).HRCNFG.bit.EDGMODE = HR_BEP; // MEP control on both edges.
(*ePWM[j]).HRCNFG.bit.EDGMODEB = HR_BEP; // MEP control on both edges
(*ePWM[j]).HRCNFG.bit.CTLMODE = HR_CMP; // CMPAHR and TBPRDHR HR control.
(*ePWM[j]).HRCNFG.bit.CTLMODEB = HR_CMP; // CMPBHR and TBPRDHR HR control
(*ePWM[j]).HRCNFG.bit.HRLOAD = HR_CTR_ZERO_PRD; // load on CTR = 0 and CTR = TBPRD
(*ePWM[j]).HRCNFG.bit.HRLOADB = HR_CTR_ZERO_PRD; // load on CTR = 0 and CTR = TBPRD
(*ePWM[j]).HRCNFG.bit.AUTOCONV = 0; // Enable autoconversion for HR period
(*ePWM[j]).HRPCTL.bit.TBPHSHRLOADE = 1; // Enable TBPHSHR sync (required for updwn count HR control)
(*ePWM[j]).TBCTL.bit.PHSEN = 0; //Prise en compte de la phase
(*ePWM[j]).TBPHS.bit.TBPHS = 0; //Dephasage
(*ePWM[j]).TRREM.bit.TRREM = 0; //Dephasage haute resolution (marche pas en mode control de position des fronts (HR_CMP))
(*ePWM[j]).HRPCTL.bit.HRPE = 1; // Turn on high-resolution
// period control.
}
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Enable TBCLK within
// the EPWM
(*ePWM[1]).TBCTL.bit.SWFSYNC = 1; // Synchronize high
// resolution phase to
// start HR period
EDIS;
And this function is used to define the CMP register (for the example the phase shift is set to 0, all the PWM should be the same)
The tricky part is to obtain the Q16 format for the CMPHR with up and down count (I find the explanations in the technical reference manual not very clear on this question).
void definirCommutation(int j, float period)
{
float intermediaire;
int intermediaireInt;
if (1)//(j==1 || j==4)
{
intermediaire=period/2;
(*ePWM[j]).CMPA.bit.CMPA = (int) floorf(intermediaire); // set duty 50% initially
intermediaireInt=((int) (intermediaire*16))-((int)(floorf(intermediaire)*16));
(*ePWM[j]).CMPA.bit.CMPAHR=intermediaireInt<<(4+8);
(*ePWM[j]).CMPB.bit.CMPB = (int) ceilf(intermediaire); // set duty 50% initially
intermediaireInt=((int)(ceilf(intermediaire)*16))-((int)(intermediaire*16));
(*ePWM[j]).CMPB.bit.CMPBHR=intermediaireInt<<(4+8);
(*ePWM[j]).AQCTLA.bit.CAU = AQ_SET; // PWM toggle high/low
(*ePWM[j]).AQCTLA.bit.CBD = AQ_CLEAR;
}
Thank you for your help
Benjamin LOYER