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.

CCS/LAUNCHXL-F28379D: HRPWM synchronisation

Part Number: LAUNCHXL-F28379D
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

  • Benjamin,

    I am working through your question. The first thing I want to mention is that TBPHSHR is not to be used. Instead we use the TRREM register.

    Have you looked at the HR Duty and Period example in c2000ware?

    Nima

  • Thank you for your answer, You are right, I did used it in preceding tests but for this one, as PHSEN=0, i figured the values in TBPHSHR, TBPHS and TRREM would not be very usefull ?

    In HRDuty, the 3.4ns delay is present and in HR period up down the PWM are not synchronised.

    I tried to use different frequencies from 300kHz to 3MHz and the delay remains the same. So if I don't find the origin, I could take care of it by software. 

    Benjamin

  • So just to clarify one thing, you are NOT using PHSEN AT ALL? You are manually trying to make the PWMs all run at the same time base and then use CMP and CMPHR to generate pahses at an offset, and the EPWM3 module is off by 3.4ns?

    Nima

  • Hello Nima,

    Yes, in this example I did not use the phase shifting module. But finally, as I wanted to be able to modify the PWM frequency, I set three modes and use the phase shift module (in low resolution) with a 0 phase shift. Mode 1 is to select the frequency with an external potentiometer, mode 2 send a software sync pulse and mode 3 is idle.

    I do not remember exactly what solved my problem but I think that was due to the automatic conversion module that was deactivated (for tests and I forgot to reenable it ...) while calculus where done taking it into account.

    Thank you for your help

    Benjamin