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.

HR PWM problem

Other Parts Discussed in Thread: CONTROLSUITE

I am having a problem with HRPWM on 28377. Here is how I set it up:

  1. I am running ePWM at 200MHz rate:

    ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV = 0;

  2. I enabled HRPWM clock:

    CpuSysRegs.PCLKCR0.bit.HRPWM = 1;

  3. I configured ePWM1 and ePWM2 to create phase shifted 50% clock:

       // TBCLK = EPWMCLK / (HSPCLKDIV * CLKDIV) => 200MHz / (1 * 1) = 200MHz

EALLOW;

CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;   // Enable TBCLK within the ePWM

// EPWM Module 1 config - Phase A PWM

EPwm1Regs.TBPRD = PWM_Counts;

EPwm1Regs.CMPA.bit.CMPA = PWM_Counts / 2;

EPwm1Regs.TBPHS.bit.TBPHS = 0;             // Set Phase register to zero

EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;

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

EPwm1Regs.TBCTL.bit.PRDLD = TB_IMMEDIATE;

EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Sync down-stream module

EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;       // CLKDIV = 1

EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;   // HSPCLKDIV = 1, TBCLK = 200MHz

EPwm1Regs.TBCTL.bit.PHSDIR = TB_UP;         // counts up after synchronization

EPwm1Regs.TBCTL.bit.FREE_SOFT = 3;         // Free run

EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;

EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;

EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;

EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_LD_DISABLE;

EPwm1Regs.CMPCTL2.bit.LOADCMODE = CC_LD_DISABLE;

EPwm1Regs.CMPCTL2.bit.LOADDMODE = CC_LD_DISABLE;

EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module

EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;     // Active Hi complementary

EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;         // EPWM1A is source for both delays

EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;           // set actions for EPWM1A AQ_SET

EPwm1Regs.AQCTLA.bit.CAD = AQ_NO_ACTION;

EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;

EPwm1Regs.AQCTLA.bit.PRD = AQ_NO_ACTION;

EPwm1Regs.AQCTLA.bit.CBU = AQ_NO_ACTION;

EPwm1Regs.AQCTLA.bit.CBD = AQ_NO_ACTION;

EPwm1Regs.DBFED.bit.DBFED = 10;

EPwm1Regs.DBRED.bit.DBRED = 10;

EPwm1Regs.TZSEL.bit.OSHT1 = TZ_DISABLE;

EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO;

EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_LO;

EPwm1Regs.TZEINT.bit.OST = TZ_DISABLE;

 

// EPWM Module 2 config - SiC1 Phase B PWM

EPwm2Regs.TBPRD = PWM_Counts;

EPwm2Regs.CMPA.bit.CMPA = PWM_Counts / 2;

EPwm2Regs.TBPHS.bit.TBPHS = 0;             // Set Phase register to zero

EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;

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

EPwm2Regs.TBCTL.bit.PRDLD = TB_IMMEDIATE;

EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // sync flow-through

EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;       // CLKDIV = 1

EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;   // HSPCLKDIV = 1

EPwm2Regs.TBCTL.bit.PHSDIR = TB_UP;         // counts up after synchronization

EPwm2Regs.TBCTL.bit.FREE_SOFT = 3;         // Free run

EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;

EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;

EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;

EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_LD_DISABLE;

EPwm2Regs.CMPCTL2.bit.LOADCMODE = CC_LD_DISABLE;

EPwm2Regs.CMPCTL2.bit.LOADDMODE = CC_LD_DISABLE;

EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module

EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;     // Active Hi complementary

EPwm2Regs.DBCTL.bit.IN_MODE = DBA_ALL;         // EPWM1A is source for both delays

EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;           // set actions for EPWM1A AQ_SET

EPwm2Regs.AQCTLA.bit.CAD = AQ_NO_ACTION;

EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;

EPwm2Regs.AQCTLA.bit.PRD = AQ_NO_ACTION;

EPwm2Regs.AQCTLA.bit.CBU = AQ_NO_ACTION;

EPwm2Regs.AQCTLA.bit.CBD = AQ_NO_ACTION;

EPwm2Regs.DBFED.bit.DBFED = 10;

EPwm2Regs.DBRED.bit.DBRED = 10;

EPwm2Regs.TZSEL.bit.OSHT1 = TZ_DISABLE;

EPwm2Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // Force low id trips

EPwm2Regs.TZCTL.bit.TZB = TZ_FORCE_LO;

EPwm2Regs.TZEINT.bit.OST = TZ_DISABLE;

EPwm2Regs.HRCNFG.bit.EDGMODE = HR_BEP; // Both edges

EPwm2Regs.HRCNFG.bit.CTLMODE = HR_PHS; // Phase control

EPwm2Regs.HRCNFG.bit.SELOUTB = HR_INVERT_B; // PWMB is inverted PWM A

EPwm2Regs.HRCNFG.bit.AUTOCONV = 1; // automatic scaling enabled

EPwm2Regs.HRMSTEP.bit.HRMSTEP = 33; // (1/200MHz)/150ps = 33.33

....

EDIS;

  1. I ran the initialization code and halted the program at a convenient point. I used the debugger to change the content of TBHS and TBHSHR registers. When I change" EPwm2Regs.TBPHS.bit.TBPHS"  I see PWM2 phase shifts with respect to PWM1. However no matter what I wright into upper 8 bits of TBPHHR I do not see PWM edge move. I think if I wright value 32 it should jump almost 5ns (almost one 200MHz clock). But it does not happen.

    What am I doing wrong? Thank you.

    Slobodan Gataric

  • Hi,

    Max operating frq for ePWM/HRPWM on this device is 100MHz. It can not operate at 200MHz.

    Please change the following code to have divide by 2 (100MHz) and see if that helps.

    ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV = 1;

    Regards,

    Vivek Singh

  • ePWM can operate at 200MHz. I am running it wright now and watching PWM waveforms on an oscilloscope. Everything looks correct: period, dead time, and phase shift between PWM1 and PWM2. I will check if HR PWM starts working if the EPWMCLK is 100 Mhz on Monday.
  • Hi,

    Please refer "Table 5-12. Internal Clock Frequencies" in device datasheet for max operating frq of ePWM. It may operate @200MHz in some mode and in some specific conditions but TI does not guarantees it to work in all conditions/devices.

    Your problem may not be related to higher frq but to start with, you should operate the device with-in max frq range provided in device datasheet.

    Regards,

    Vivek Singh

  • Lowering PWM clock to 100MHz did not help. It behaves exactly the same. No matter what I type into TBPHSHR, the PWM edge does not move. I did change HRMSTEP register because the clock is 100MHz now:
    EPwm2Regs.HRMSTEP.bit.HRMSTEP = 66; // (1/100MHz)/150ps = 66.6

    Here are my questions:
    1. Did I configure everything correctly? Please go over the PWM configuration on the top of the page.
    2. When I halt the program and use "Registers" tab to change values of TBPHSHR, should I see the PWM edge move accordingly?
    3. My understanding is that I need to modify upper byte of TBHSHR. In this particular case, the upper byte should be in the range 0 to 66, to get the edge move 0 - 10ns. Is that correct?
    4. I am not understanding the automatic scaling. Does it change what I need to write into TBHSHR depending on if it is enabled or not? Could you give me an example of the TBHSHR value using my configuration for moving the edge 5ns (one half of 10ns) ? Is it 33 for both automatic scaling enabled and not enabled?

    Could you answer EACH question separately please?

    Slobodan Gataric
  • Hi Slobodan,

    1. Did I configure everything correctly? Please go over the PWM configuration on the top of the page.
    >> Configuration seems correct to me. I believe your goal is to achieve high resolution phase shift between EPWM1 and EPWM2 - but not Hi-resolution duty cycle control. Correct?
    Did you try writing to TBPHSHRLOADE bit? Details in Table 14-30. HRPCTL Register Field Descriptions

    2. When I halt the program and use "Registers" tab to change values of TBPHSHR, should I see the PWM edge move accordingly?
    >> I would expect so. The TBPHSHR value should reflect in the phase shift.

    3. My understanding is that I need to modify upper byte of TBHSHR. In this particular case, the upper byte should be in the range 0 to 66, to get the edge move 0 - 10ns. Is that correct?
    >> You need to call the SFO library for calibration and enable AUTOCONV. You don't have to write to HRMSTEP or worry about scaling the value from 0-66 for 0-10ns etc. You can write value assuming full scale (0 to 0xFF) and the hardware takes care of the scaling as needed.
    But for the purpose of testing - what you are doing above should result in some phase shift.

    4. I am not understanding the automatic scaling. Does it change what I need to write into TBHSHR depending on if it is enabled or not? Could you give me an example of the TBHSHR value using my configuration for moving the edge 5ns (one half of 10ns) ? Is it 33 for both automatic scaling enabled and not enabled?
    >> Yes - you just need to write assuming full scale (0-0xff). for ex: for 50% you may write 0x80. Hardware automatically scales it to the 50% value. To answer your question - yes, it does change the value to be written to TBPHSHR based on AUTOCONV is enabled or not. But I suggest you always use AUTOCONV and assume full range and let hardware do the scaling.
  • I thought that not setting TBPHSHRLOADE bit to 1 was the source of my problem. But it is not. I set it and still the PWM edge does not move at all. Do I need to run SFO()? Is it mandatory for HR PWM to work? At this time, I do not care about calibration , I just want to see the edge move.

    I searched the TRM and found the explanation on how to use SFO(), but I am missing something. I searched all files in "C:\TI\controlSUITE\device_support\F2837xD\v190\" and found two files that call SFO, "hrpwm_duty_sfo_v8.c" and "hrpwm_prdupdown_sfo_v8.c". However they have main() function inside, so they are just examples. Where is the source for SFO() ? I did not find it.

    S. Gataric
  • This way of debugging a problem is not going to work. I need to TALK to technical support. Exchanging 2 emails a day is not productive.
    The linker does not know where SFO() is. It is unresolved. TI doscumetation does not say at all what needs to be included to get SFO resolved. That is (usual TI) bad documentation. If I am wrong, please point out where it is spelled our what library needs to be included. I challenge you to do so!

    Here are liker flags:

    -v28 -mt -ml --vcu_support=vcu2 --cla_support=cla1 --tmu_support=tmu0 --float_support=fpu32 -O2 --opt_for_speed=5 --fp_mode=relaxed --advice:performance=all -g --define=CPU1 --define=_INLINE --define=CPU_FRQ_200MHZ --diag_warning=225 --diag_wrap=off --display_error_number -z -m"BidiCore1_Ram.map" --stack_size=0x100 --warn_sections -i"C:/TI6/ccsv6/tools/compiler/ti-cgt-c2000_6.4.9/lib" -i"C:/TI6/ccsv6/tools/compiler/ti-cgt-c2000_6.4.9/include" -i"D:/workspace_v6_1/Bidi/CustomLibraryCPU1/Debug" --reread_libs --diag_wrap=off --display_error_number --xml_link_info="BidiCore1_linkInfo.xml" --ram_model

    What is missing? Where is the SFO source or library?
  • Last update:

    I turned off AUTOCONV bit and now it works. When AUTOCONV is set to 1 it does not work.

    I am done wasting time on this problem. I will not use AUTOCONV and be done with it.

    Thank you to all who responded.

  • Hi Everyone!

    Has this been resolved by any method other than turning off autoconversion?

    I have the same problem, with some more information.

    I can make HRPWM work with CMPA/CMPB, but cannot make the HR phase shift work.  The SFO library is working properly and generating a MEP_ScaleFactor of 65 or so.  I should also say that I'm using an old development kit with TMX version silicon.  Is this a known issue that's been fixed in the TMS versions?

    Justin

  • Justin,

    I am using a 28377 eval board with TMS part, not TMX part. I do not think it has to do anything with using TMX part.

    Not using autoconversion is not a penalty at all. It is one extra multiplication. I got phase shifting work correctly without AUTOCONV bit. Took me a week to figure out how to properly scale duty cycle into phase shift register bits. You will need to treat PWM bits differently than HR PWM bits. Unfortunately I can not share the code, because of GE policy. Good luck.

    Gasha

  • Hi Gasha!

    I must be doing something else wrong- even turning off autoconv doesn't fix it.

    Justin