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/TMS320F28033: Missing pulse when using THPHS

Part Number: TMS320F28033
Other Parts Discussed in Thread: UCD3138

Tool/software: Code Composer Studio

Hi, 

We have included TMS320F28033PAG in our design to control an H bridge (four IGBT:s)

This is a frequency controlled LLC bridge

This is done by using two main output PWMs with one shadow PWM each that runs 180 degrees phase shifted with dead time.

However, we see problem with one of the PWMs (main and shadow) when phase shifting it compared to the other main PWM

Of we have zero on phase shifting at start (TBPHS=0) we see a missing pulse when starting to increase the phase shift to a very small value, see picture below

If we start the pwm set with a very small phase shift (TBPHS = 0.001) at initialization we see the missing pulse directly when the microcontroller starts to generate pulses at the PWMs, see picture below

We do not want to see any missing pulses.

Is this possible to perform?

See the init setup of the PWMs below

Are we using this in a incorrect way?

Thank you

Best regards

John

EPwm1Regs.TBCTL.bit.PRDLD = TB_IMMEDIATE; //TB_SHADOW;

            EPwm1Regs.TBPRD = (MD_DRIVER_PERIOD_CYCLES - 1);

            EPwm1Regs.CMPA.half.CMPA = (MD_DRIVER_PERIOD_CYCLES / 2);  // 0;

            //EPwm1Regs.CMPA.half.CMPA = 0; // No pulses

            EPwm1Regs.TBPHS.half.TBPHS = ZERO_PHASE_SHIFT;//0;                                                           // Set phase register to 0

            EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;                  // Count up

            EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;                                  // Master module

            EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;

            EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;                                    // No prescaler

            EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;

 

            EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;

            EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;

            EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_PRD; //CC_CTR_ZERO;

            EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_PRD; //CC_CTR_ZERO;

 

            EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;

            EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;

 

            EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;  // Deadband enabled

            EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;                   // Activate complementary B-channel

            EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;                                   // EPWMxA is the source for both falling- and rising-edge delays

            EPwm1Regs.DBRED = DRIVER_RISING_EDGE_DELAY_CYCLES; //counter clocked by system clock 60MHz

            EPwm1Regs.DBFED = DRIVER_FALLING_EDGE_DELAY_CYCLES;

 

            //////////////////////////

            // PWM 2

            EPwm2Regs.TBCTL.bit.PRDLD = TB_IMMEDIATE; //TB_SHADOW;

            EPwm2Regs.TBPRD = (MD_DRIVER_PERIOD_CYCLES - 1);

            EPwm2Regs.CMPA.half.CMPA = (MD_DRIVER_PERIOD_CYCLES / 2);  // 0;

            //EPwm2Regs.CMPA.half.CMPA = 0;

            EPwm2Regs.TBPHS.half.TBPHS = ZERO_PHASE_SHIFT;//0;                                                           // Set phase register to 0 initially

            EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;                  // Count up

            EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;                                   // Slave module

            EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;                  // Sync

            EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;                                    // No prescaler

            EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;

 

            EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;

            EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;

            EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_PRD; //CC_CTR_ZERO;

            EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_PRD; //CC_CTR_ZERO;

 

            EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;

            EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;

 

            EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;  // Deadband enabled

            EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;                   // Activate complementary B-channel

            EPwm2Regs.DBCTL.bit.IN_MODE = DBA_ALL;                                   // EPWMxA is the source for both falling- and rising-edge delays

            EPwm2Regs.DBRED = DRIVER_RISING_EDGE_DELAY_CYCLES;

            EPwm2Regs.DBFED = DRIVER_FALLING_EDGE_DELAY_CYCLES;

  • Hi John,

    The issue that you are seeing is possibly what is being described in the note for Figure 3-14: Counter-Compare Event Waveforms in Up-Count Mode within the F2803x Technical Reference Manual

    You could try the following:

    1) Move your synchronization point away from your PWM edge.

    2) Use CMPA/CMPB instead of CMPA/ZRO (try setting your CMPx values larger than your max TBPHS value). Refer to  this thread, as it gives a good explanation for a workaround. 

    Another possible resource is this thread

    Best Regards,

    Marlyn

  • hi,

    sure we can use the CMPA/CMPB. 

    But, we are not sure how to do this.

    Could you please provide us with a working set of registry settings?

    The settings we are using at the moment is provided earlier in this thread.

    We are using the:

    EPwm2Regs.TBPHS.half.TBPHS to enable up to 180 degrees phase shift today. But with this, we see the miss in pulses.

    So, how should we do this by using the CMPA/CMPB instead?

    Thank you

    Best regards

    John

  • Hi John,

    Apologies for the delay as a lot of us were out of the office due to the holidays. 

    Were you able to progress further in this issue?

    The links that I provided in my previous post describe work arounds that could help resolve your issue. When you calculate a new TBPHS value you should also check whether the new TBPHS may cause a jump in the counter value that might skip the CMPA event. If this is the case, then you should change the CMPA value to 'TBPHS+1' for just one cycle. The CMPA value should be changed back to the original value in the following cycle. (Refer to this thread).

    Best Regards,

    Marlyn

  • Hi,

    I did manage to get rid of the missing pulse, but now we see a temporary change in frequency at the same moment.

    See 4 seconds in in the attached movie. The yellow and blue PWM:S shows a change in frequency.

    You can see the softstart feature by following the phase shift in the purple pwm.

    I set the phase shift by:

    EPwm2Regs.TBPHS.half.TBPHS = phaseShift;

    PhaseShift is a value between 1 and 600 that fits the other configured values.

    the EPwm2Regs is the slaving pwm with:

    EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;

    I was able to get rid of the missing pulse by checking the following:

    if(EPwm1Regs.TBCTR > EPwm1Regs.CMPA.half.CMPA)
    {
    //change in phase has made the counter to be above the CMPA
    //problem
    EPwm1Regs.TBCTR = EPwm1Regs.CMPA.half.CMPA;

    }

    so what I do is that I change the TBCTR when I see that it is above the CMPA. This is done inside the function triggered by the CMPA and after the phase shift has been updated.

    This was the only way I managed to get rid of the missing pulse. However, I got the temporary change in frequency instead.

    Am I doing this in the correct way?

    Can I then also get rid of the change in frequency when this occurs?

    We have found another controller that perhaps is more aimed for controlling an LLC: UCD3138

    Is it better to use this instead? Or, should it be possible to get our microcontroller to function properly?

    Is the another controller for controlling a state vector PFC?

    thank you

    Best regards

    John Melin

     

  • Hi John,

    A few questions for you to get a better idea of what is happening.

    What is the value of MD_DRIVER_PERIOD_CYCLES?

    John Melin said:
    This is done inside the function triggered by the CMPA and after the phase shift has been updated.

    Are you updating the phase shift every time there is a CMPA event?

    John Melin said:
    I got the temporary change in frequency instead.

    When you say "temporary", do you mean the frequency changes again the next time you change the phase shift value?

    I do not know about the UCD3138 part as this is the C2000 E2E Forum, but what you are hoping to accomplish should be possible with the current microcontroller. 

    Best Regards,

    Marlyn

  • hi

    MD_DRIVER_PERIOD_CYCLES equals 1200

    I have reviewed this in a little more detail. and it looks like it is the duty cycle that changes.

    It changes and stays there until the phase is not changing anymore, or until the another part of the code is executed.

    Perhaps this condition is fulfilled during the rest of the soft start:

    if(EPwm1Regs.TBCTR > EPwm1Regs.CMPA.half.CMPA)

    {

    EPwm1Regs.TBCTR = EPwm1Regs.CMPA.half.CMPA;

    }

    I tried to set the EPwm1Regs.TBCTR = EPwm1Regs.CMPA.half.CMPA -1;

    But that did not work as I remember

     

    regarding: Are you updating the phase shift every time there is a CMPA event?

    Sorry about this, it is done in the following way:

    - CMPB is set to 200 and triggers and ADC conversion.

    - when ADC conversion is done it triggers a task in the CLA.

    -this task is updating the phase and checks the condition for:

    if(EPwm1Regs.TBCTR > EPwm1Regs.CMPA.half.CMPA)

    {

    EPwm1Regs.TBCTR = EPwm1Regs.CMPA.half.CMPA;

    }


    I guess that it is the change in TBCTR that affects the duty cycle, correct?

    Where you able to see the attached movie?

    I am kind of new to all this registry settings so please excuse me for that.

    I tried to changed the CMPA value temporary, but it did not resolve the missing pulse.

    Any suggestion?

    Thank you

    Best regards

    John

     

  • Hi John,

    John Melin said:
    this task is updating the phase

    Can I please see how you are changing the phase in this function? I had assumed that ePWM1 was your main PWM and ePWM2 was your secondary PWM based on the code you provided. In this case, changing the TBCTR count for EPWM1 could cause all of your waveforms to change. 

    The missing pulse indicates that the EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR; event is missed when you change the phase since the signal stays high. 

    Have you already tried to remove the deadband portion of your code for debugging purposes? Sometimes its best to isolate the different components of the ePWM module and work up from there.

    Also, for debugging can you please create an interrupt from the ePWM module and change the phase to a fixed value there, does it still show a missing pulse? The timing for the adc conversion could be affecting the operation so it is good to rule this out. 

    Best Regards,

    Marlyn

  • hi, 

    Please find the code for changing the phase below:

    if( phaseShift < (MD_DRIVER_PERIOD_CYCLES / 2)) // Max 180 degrees phase shift
    {

    //using fixed frequency during softstart
    //ramping up the duty cycle up to 50%

    softStartCounter ++;

    if(softStartCounter >= NUM_OF_COUNTS_TO_PERFORM_2_SEC_START)
    {

    if(phaseShift < (MD_DRIVER_PERIOD_CYCLES / 2))
    {
    phaseShift ++;
    }

    softStartCounter = 0;

    }

    EPwm2Regs.TBPHS.half.TBPHS = phaseShift;

    EPwm1Regs.TBPRD = (MD_DRIVER_PERIOD_CYCLES - 1); //50khz
    EPwm2Regs.TBPRD = (MD_DRIVER_PERIOD_CYCLES - 1);
    EPwm1Regs.CMPA.half.CMPA = (MD_DRIVER_PERIOD_CYCLES / 2); // 0;
    EPwm2Regs.CMPA.half.CMPA = (MD_DRIVER_PERIOD_CYCLES / 2); // 0;


    if(EPwm1Regs.TBCTR > EPwm1Regs.CMPA.half.CMPA)
    {
    //change in phase has made the counter to be above the CMPA
    //problem
    EPwm1Regs.TBCTR = EPwm1Regs.CMPA.half.CMPA;

    }

    }
    else
    {

    //running normal operation

    period_err = (1 + 0.2 * cla_vout) - period; // 0V -> 100%, 2V -> 140%
    //0V = 50KHz
    //3V = 35KHz
    period = period + period_err * PERIOD_REG_P; // P-regulation of period

    period_cycles = (Uint16)(MD_DRIVER_PERIOD_CYCLES * period + 0.5);

    EPwm1Regs.TBPRD = period_cycles - 1;
    EPwm1Regs.CMPA.half.CMPA = period_cycles >> 1;

    EPwm2Regs.TBPRD = period_cycles - 1;
    EPwm2Regs.CMPA.half.CMPA = period_cycles >> 1;

    //phase needs to be updated when changing frequency
    EPwm2Regs.TBPHS.half.TBPHS = period_cycles >> 1;
    }
    }

    so this occurs during softstart.

    I agree with you PWM1.TBCTR. I should be changing the TBCTR for PWM2 is anyone, right?

    But this does not seem to be right, in other threads they say that I should temporary be changing the CMPA. But I am unable to get this to work

    I cannot test anything at the moment cause the microcontroller is being tested in the real hardware. I will get it back next week hopefully.

    Meantime, it would be good to know what I should do the get rid of the missing pulse during update of the phase.

    I have not tried to remove the deadtime. We need this for our application and cannot remove it, therefore I have not tried it for debugging purpose either.

    however, If I remove the change in phase, the problem goes away

    Here is the configuration values for the PWMs

    EPwm1Regs.TBCTL.bit.PRDLD = TB_IMMEDIATE; //TB_SHADOW; Load the TBPRD register immediately without using a shadow register.
    //A write or read to the TBPRD register directly accesses the active register

    EPwm1Regs.TBPRD = (MD_DRIVER_PERIOD_CYCLES - 1);//(MD_DRIVER_PERIOD_CYCLES - 1); //50khz
    EPwm1Regs.CMPA.half.CMPA = (MD_DRIVER_PERIOD_CYCLES / 2); // 0; //50% duty
    EPwm1Regs.CMPA.half.CMPA = 0; // Start with No pulses
    EPwm1Regs.TBPHS.half.TBPHS = ZERO_PHASE_SHIFT;//0; // Set phase register to 0
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
    EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Master module
    EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;
    EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; // No prescaler
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;

    EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Shadow mode. Operates as a double buffer. All writes via the CPU access the shadow register
    EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // Shadow mode. Operates as a double buffer. All writes via the CPU access the shadow register
    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_PRD; // Load on CTR = PRD: Time-base counter equal to period (TBCTR = TBPRD)
    EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_PRD; //CC_CTR_ZERO;

    EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; //Action when counter equals zero.
    // 2: Set: force EPWMxA output high.
    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; //Action when the counter equals the active CMPA register and the counter is incrementing.
    //Clear: force EPWMxA output low

    EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // Deadband enabled
    EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Activate complementary B-channel
    EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL; // EPWMxA is the source for both falling- and rising-edge delays
    EPwm1Regs.DBRED = DRIVER_RISING_EDGE_DELAY_CYCLES; //counter clocked by system clock 60MHz
    EPwm1Regs.DBFED = DRIVER_FALLING_EDGE_DELAY_CYCLES;

    //////////////////////////
    // PWM 2
    EPwm2Regs.TBCTL.bit.PRDLD = TB_IMMEDIATE; //TB_SHADOW;
    EPwm2Regs.TBPRD = (MD_DRIVER_PERIOD_CYCLES -1);//(MD_DRIVER_PERIOD_CYCLES - 1);
    EPwm2Regs.CMPA.half.CMPA = (MD_DRIVER_PERIOD_CYCLES / 2); // 0;
    EPwm2Regs.CMPA.half.CMPA = 0;

    EPwm2Regs.TBPHS.half.TBPHS = ZERO_PHASE_SHIFT; //(MD_DRIVER_PERIOD_CYCLES / 2); // FIXME:ZERO_PHASE_SHIFT;//0; // Set phase register to 0 initially
    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
    EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Slave module
    //Load the time-base counter with the phase register when an EPWMxSYNCI input signal occurs or
    //when a software synchronization is forced by the SWFSYNC bit

    EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Sync EPWMxSYNC


    EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1; // No prescaler
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;

    EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_PRD; //CC_CTR_ZERO;
    EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_PRD; //CC_CTR_ZERO;

    EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;
    EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;

    EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // Deadband enabled
    EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Activate complementary B-channel
    EPwm2Regs.DBCTL.bit.IN_MODE = DBA_ALL; // EPWMxA is the source for both falling- and rising-edge delays
    EPwm2Regs.DBRED = DRIVER_RISING_EDGE_DELAY_CYCLES;
    EPwm2Regs.DBFED = DRIVER_FALLING_EDGE_DELAY_CYCLES;

    //////////////////////////
    // Interrupt and Events

    // Control of ADC
    EPwm1Regs.CMPB = DRIVER_ADC_EVENT_DELAY; // Delay for ADC Event
    EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group
    EPwm1Regs.ETSEL.bit.SOCASEL = ET_CTRU_CMPB; /*ET_CTR_ZERO;*/ /*ET_CTR_PRD;*/ // Event dependent of CMPB
    EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate event every period

    EALLOW;
    PieVectTable.EPWM1_INT = &DriverPeriodISR;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Enable TBCLK
    EDIS;

    PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Fetch vectors from vector table
    PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
    IER |= M_INT3;

    Thank you 

    Best regards

    John

  • John,

    One thing that could be happening is that the following piece of code may be executing for the case when phaseShift is equal to 599 considering your MD_DRIVER_PERIOD_CYCLES value is 12000:

    if(phaseShift < (MD_DRIVER_PERIOD_CYCLES / 2))
    {
    phaseShift ++;
    }

    At this point the phaseShift is 600 (599+1)

    Then you set the phase EPwm2Regs.TBPHS.half.TBPHS = phaseShift;

    This may be causing the event on the action qualifier to be missed EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;

    Instead of checking for when the TBCTR counter for EPWM1 is greater than CMPA, try checking if the phaseShift is >= CMPA of EPWM2 in which case you want to set CMPA to be phaseShift +1 just for that cycle so that the event on CAU can occur. 

    Was this what you tried earlier when you mentioned "I tried to changed the CMPA value temporary, but it did not resolve the missing pulse"?

    Best Regards,

    Marlyn

  • Hi,

    you mean like this:

    if(EPwm2Regs.TBPHS.half.TBPHS >= EPwm2Regs.CMPA.half.CMPA)
    {
    EPwm2Regs.CMPA.half.CMPA = EPwm2Regs.TBPHS.half.TBPHS +1;
    }

    ?

    I will verify this next week when getting the microcontroller back

    Best regards

    John

  • Hi John,

    Yes, please try that when you are able.

    Best Regards,

    Marlyn

  • Hi,

    I now have access to the controller board

    I have now tried the:

    if(EPwm2Regs.TBPHS.half.TBPHS >= EPwm2Regs.CMPA.half.CMPA)
    {
    EPwm2Regs.CMPA.half.CMPA = EPwm2Regs.TBPHS.half.TBPHS +1;

    And it does not affect the missing PWM pulse when changing phase shift.

    I also tried to disable the dead band but that did not resolved the issue either.

    The only thing that seems to keep all the pulses good enough is the following:

    if(EPwm1Regs.TBCTR > EPwm1Regs.CMPA.half.CMPA)
    {
    //change in phase has made the counter to be above the CMPA
    //problem
    EPwm1Regs.TBCTR = EPwm1Regs.CMPA.half.CMPA;

    //EPwm2Regs.TBCTL.bit.SWFSYNC = 0x1;

    }

    but it affects the pulses in other ways.

    I do not want to guess here, we cannot have a solution that we are not really sure will work 100%

    Please advice

    Thank you 

    Best regards

    John

  • One of the most commong causes of a missing pulse, or an AQ action being missed is that when TBPSH is being update, the value is larger than CMPA/CMPB/PRD, and hence the action is skipped. If it is necessary for the action to occur when the CMPx/PRD is skipped, you need to also update the CMPx value to be larger than TBPHS.

    Nima

  • Hi

    When you say: the value is larger than CMPA/CMPB/PRD, and hence the action is skipped


    Do you mean that the following should do the job:

    if(EPwm2Regs.TBPHS.half.TBPHS >= EPwm2Regs.CMPA.half.CMPA)
    {
    EPwm2Regs.CMPA.half.CMPA = EPwm2Regs.TBPHS.half.TBPHS +1;
    }

    Only solution that seems to be working is:

    if(EPwm1Regs.TBCTR > EPwm1Regs.CMPA.half.CMPA)
    {
    //change in phase has made the counter to be above the CMPA
    //problem
    EPwm1Regs.TBCTR = EPwm1Regs.CMPA.half.CMPA;

    }

    Do you then mean that I should try:

    if(EPwm1Regs.TBPHS.half.TBPHS >= EPwm1Regs.CMPA.half.CMPA)
    {
    EPwm1Regs.CMPA.half.CMPA = EPwm1Regs.TBPHS.half.TBPHS +1;
    }

    Instead?

    I use the phase on PWM2 to adjust the phase shift:

    EPwm2Regs.TBPHS.half.TBPHS = phaseShift;

    Should I not check the PWM2 against phase and CMPA?

    Thank you

    Best regards

    John

  • Hi John,

    The code below should check for when "the value is larger than CMPA/CMPB/PRD" in your case.

    if(EPwm2Regs.TBPHS.half.TBPHS >= EPwm2Regs.CMPA.half.CMPA)
    {
    EPwm2Regs.CMPA.half.CMPA = EPwm2Regs.TBPHS.half.TBPHS +1;
    }

    Could you please try putting a breakpoint on this if-statement and check if the condition is ever met? Now, if the code does enter the if-statement then please check the value of CMPA and TBPHS at the time of occurrence, you can set a break-point and read the values from the watch expression window in CCS. Before you leave the function that updates the phase shift value I would suggest to also check the value of CMPA/TBPHS to make sure nothing got overwritten. This last part should be done even in the case that the if statement didn't get executed. This will give us a better understanding of what is happening.

    Best Regards,

    Marlyn

  • Hi

    I still see missing pulse with the following code:

    if(EPwm2Regs.TBPHS.half.TBPHS >= EPwm2Regs.CMPA.half.CMPA)
    {
    EPwm2Regs.CMPA.half.CMPA = EPwm2Regs.TBPHS.half.TBPHS +1;
    }

    In this case the IF-statement is entered with TBPHS = 600 and CMPA = 600


    But if I add the following, the missing pulse goes away but I se other problems

    if(EPwm1Regs.TBCTR > EPwm1Regs.CMPA.half.CMPA)
    {
    //change in phase has made the counter to be above the CMPA
    //problem

    EPwm1Regs.TBCTR = EPwm1Regs.CMPA.half.CMPA;

    }

    in this case the IF-statement is entered when TBCTR = 806 and CMPA = 600

    This keeps me away from the missing pulse problem.

    What am I missing.

    The missing pulse is seen on PWM2 A and B

    Please advice.

    Best regards

    John

  • Hi John,

    Did you ever check the value of CMPA/TBPHS on ePWM2 right before leaving your function to make sure nothing got overwritten?

    Best Regards,

    Marlyn

  • You need to have a check everytime you do your calculation and you are about to update TBPHS. Rigth after you write to TBPHS, you need to make sure the CMPx value is after or before the TBPHS value based on the PHASE DIR register.

  • If you do this and put an incrementing variable inside the if statement which checks this, you can see exactly how many times you execute to condition.

  • Hi

    with the following:

    if(EPwm2Regs.TBPHS.half.TBPHS >= EPwm2Regs.CMPA.half.CMPA)
    {

    EPwm2Regs.CMPA.half.CMPA = EPwm2Regs.TBPHS.half.TBPHS +1;
    failureCounter ++;

    }

    failureCounter reached 1

    with the following solutions that actually affects the missing pulse:

    if(EPwm1Regs.TBCTR > EPwm1Regs.CMPA.half.CMPA)
    {
    //change in phase has made the counter to be above the CMPA
    //problem

    EPwm1Regs.TBCTR = EPwm1Regs.CMPA.half.CMPA;
    failureCounter ++;

    }

    failureCounter reaches 34664

    And yes, the different registries are checked vs CMPx after the phase has been updated at the end of the function.

    Please advice

    Thank you

    Best regards

    John 

  • Where do you have the code above? in an ISR or in main?

  • Hi,

    This is actually running in a CLA driven by a completion from a ADC interrupt.

    But, just to exclude this complexity, I moved the phase adjustment to the main loop and see the same issue there, I see loss in pulses when adjusting the phase

    However, It seems like the fix I tried is not bullet proof. I see loss in pulses even with this fix. Perhaps if the phase updates with another frequency.

    The fix I mean is :

    if(EPwm1Regs.TBCTR > EPwm1Regs.CMPA.half.CMPA)
    {
    //change in phase has made the counter to be above the CMPA
    //problem

    EPwm1Regs.TBCTR = EPwm1Regs.CMPA.half.CMPA;

    }

    Your suggestion:

    if(EPwm2Regs.TBPHS.half.TBPHS >= EPwm2Regs.CMPA.half.CMPA)
    {

    EPwm2Regs.CMPA.half.CMPA = EPwm2Regs.TBPHS.half.TBPHS +1;

    }

    Does not resolve the loss in pulse

    Thank you

    Best regards

    JOhn

      

  • HI John,

    Please take a look at the following document: 3187.Multi-phase Variable Frequency.pdf

    This document describes a method to change the frequency and phase. Essentially you want to change the PRD and Phase values at a known good point in your switching cycle. This is typically done within a PWM ISR. You can use the CLA task to figure out what the PRD and phase values should be, but then actually write the new values to the ePWM registers within a PWM ISR. Please read-through and try the steps in the document above and let me know the outcome.

    Best Regards,

    Marlyn

  • Also did you mention that 

    if(EPwm1Regs.TBCTR > EPwm1Regs.CMPA.half.CMPA)
    {
    //change in phase has made the counter to be above the CMPA
    //problem
    
    EPwm1Regs.TBCTR = EPwm1Regs.CMPA.half.CMPA;
    
    }

    solves the issue?

  • Hi,

    Well, it seems like it depends on the frequency in changing the phase.

    Cause in my original design, this fix removed the missing pulse. But, when I tried to move the functionality to the main loop from the CLA this fix did not work.

    But running the function that updates the phase made this fix to work again.

    Really strange.

    Best regards

    John

  • Hi John,

    Please try to follow the steps that are outlined within the document I previously linked. Changing the value of TBCTR for ePWM1 is not a recommended solution.

    Best Regards,

    Marlyn

  • Hi,

    I have now the redesign according to your suggestion.

    Now we have two ISRs:

    - one triggered at PWM zero that sets frequency and phase

    - one triggered at PWM midpoint that triggers ADC conversion and calculates new frequency and phase values to be used in the above ISR.

    It seems to be working. We will do some more testing  

    However, at boot up and start of the pulses we see a longer pulse, see picture:

    Can we resolve this issue?

    Thank you 

    best regards

    John

  • Hi John,

    I am glad the redesign is working for you!

    The longer pulses at the boot up could be due to the active complementary configuration within your dead-band in the initialization taking effect. One way you could possibly get around this is not muxing the GPIOs for EPWM usage until you reach your very first EPWM zero interrupt (at this point the epwm module should be fully initialized). 

    Best Regards,

    Marlyn

  • Hi,

    Now we have tested this a little bit more.

    And I am sad to tell you but we still see loss in pulses.

    Seems to be always on the 2 pwm:s affected by the phase shift.

    I also noticed that the description on how to do send earlier assumed 4 PWMs operating at constant 90 degrees phase shift.

    in our case we are performing softstart by shifting phase from 0 to 180 degrees.

    And I think that it is this change in phase that are causing this.

    now we are running the update in PWM values in a PWM driven ISR, driven by PWM1.

    The PWM values are calculated in a ADC isr activated at completion of ADC conversion and stored in local storage.

    Then the PWM values are updated synchronously  with PWM1 

    The following does not resolve it:

    if(EPwm2Regs.TBPHS.half.TBPHS >= EPwm2Regs.CMPA.half.CMPA)
    {
    EPwm2Regs.CMPA.half.CMPA = EPwm2Regs.TBPHS.half.TBPHS +1;

    }

    Nor does the following:

    if(EPwm1Regs.TBPHS.half.TBPHS >= EPwm1Regs.CMPA.half.CMPA)
    {
    EPwm1Regs.CMPA.half.CMPA = EPwm1Regs.TBPHS.half.TBPHS +1;

    }

    This does not occur every time I boot up the system.

    Could you provide us with a suggestion on how we should resolve this in a bulletproof way?

    We found some similar application on how to use the your PWM blocks:

    I do not know if this issue has been resolved in this application?

    What do you suggest?

    Thank you

    Best regards

    John

  • Hi John,

    I think its important to be able to identify which phase shift value is causing the missing event. Would it be possible for you to manually change the phase shift? Another way to go about this is by forming clusters and then narrowing down towards a specific value...do you see the missing pulse if you only do 90-180 degree phase shift or is it in the lower range? 

    Again, if you can disable the dead-band submodule during debugging that would be something I suggest.

    John Melin said:
    I do not know if this issue has been resolved in this application

    As far as I know the method introduced in the document you referenced does not yield an output with any missing pulses.

    Best Regards,

    Marlyn

  • Hi

    I have already checked the dead-band that does not affect the missing pulse. Please read the whole case to so that we do not walk in circles.

    It is kind of hard to check at what settings of the phase the missing pulse occur. This was what I was hoping of you could tell me, what special fix I need to add to get this to work.

    What you have told me earlier a change in phase might end up that the CMPA trigger is missed.

    But the check against CMPA does not seem to resolve the issue.

    Any other thing we we to handle?

    If we are not able to resolve this in a certain way we are forced to move away from this design completely.

    thank you

    Best regards

    John

  • Hi John,

    Without narrowing down the phase value that is causing the missing action it is difficult to progress or suggest a fix from my end. I spoke to a colleague and we both agreed that without that missing information its not clear how to resolve the issue. 

    It will take some debugging on your end to figure out which phase value is causing this within your system. As I previously suggested start with large ranges and narrow it down based on when you see the missing pulse occur.

    Best Regards,

    Marlyn