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.

TMS320F28069: PWM Setup Problem

Part Number: TMS320F28069


Thanks for looking at this...

I have working hw and sw, and want to add 4 new PWMs to the existing one.  ePWM1B is currently configured and working.  I'm trying to add ePWM2A and others.

Using the 80 pin part, ePWM1 is configured to use pin 68.  It's setup by a call to the following function from main():

void InitEPwm1BGpio(void)
{
   EALLOW;

/* Disable internal pull-up for the selected output pins
   for reduced power consumption */
    GpioCtrlRegs.GPAPUD.bit.GPIO1 = 1;    

/* Configure EPWM-1 pins using GPIO regs*/
    GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1;   

    EDIS;
}

So, I have duplicated this function (shown below) along with an appropriate call from main():

void InitEPwm2AGpio(void)
{
   EALLOW;

/* Disable internal pull-up for the selected output pins
   for reduced power consumption */
    GpioCtrlRegs.GPAPUD.bit.GPIO2 = 1;    

/* Configure EPwm-2 pins using GPIO regs*/
    GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1;  

    EDIS;
}

I can see in the memory browser that the above are working as expected.  The settings are finding there way into the correct memory locations.

The problem I'm having is with the next step of the setup process.

ePWM1B is being setup in the following function called from main() after the above functions have completed their jobs:

void InitEPwm(Uint16 period)
{
   EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;            
   EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_HSP_DIV1;
   EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;    
   EPwm1Regs.TBPHS.all = 0;                            
   EPwm1Regs.TBCTR = 0;                                
   EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;            
   EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;            
   EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;    

   /*
    * PWM Frequency = TBCLK / (1 + TBPRD)
    */
   EPwm1Regs.TBPRD = period;
   EPwm1Regs.CMPB = period/2;
   EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;        
   EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET;
   EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR;

   EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;
   EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_HSP_DIV1;
   EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
   EPwm2Regs.TBPHS.all = 0;
   EPwm2Regs.TBCTR = 0;
   EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;
   EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;
   EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;

   /*
    * PWM Frequency = TBCLK / (1 + TBPRD)
    */
   EPwm2Regs.TBPRD = period;
   EPwm2Regs.CMPB = period/2;
   EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
   EPwm2Regs.AQCTLB.bit.ZRO = AQ_SET;
   EPwm2Regs.AQCTLB.bit.CBU = AQ_CLEAR;

}

By single stepping through this function, I confirmed that the values being inserted in the ePWM1B structure are making it where they belong, as expected.

Here's where I'm getting lost; as I single step through the lines that should be updating the ePWM2A structure, the values remain unchanged.  They seem to begin life with all zeros, and when a line of code asserts a change from zero to '3', as is the case with "EPwm2Regs.TBCTL.bit.SYNCOSEL= TB_SYNC_DISABLE;", the change is ignored.  The value of "EPwm2Regs.TBCTL.bit.SYNCOSEL" remains zero.  (The constant 'TB_SYNC_DISABLE" is defined as 3.)

I've tried using ePWM7A, and had the same results.  I thought those registers might be in protected memory, but I couldn't find any documentation saying that.  I tried enclosing them in EALLOW & EDIS, but it didn't help.

Is there is different way to setup an 'A' PWM versus a 'B'?  I'm trying to use the 'A's, because frequency control may need the higher resolution.

I feel like I'm making an amateur mistake, but I'm just not seeing it.

Can someone help me?

Thanks,

robin

  • Hello.

    Did you call "InitSysCtrl()" in the beginning of "main"? I'm not sure about F28069, but in some MCUs you can't set up Peripherals until you set peripheral clocking.

    One more question: have you tried to run this code instead of single stepping? If you have optimization turned on (in compiler settings), stepping will act weird.

    Also you can try to change the registers in the "Expressions" or "Registers" window during debug. Are the changes applied in this case?

  • Hi Disona,

    Thanks for your reply.  Your advice helped me get to the next problem in ePWM setup.

    Yes, I was calling "InitSysCtrl()" in "main()", but it didn't include code to enable the clock on EPWM2.  I couldn't change the values from the "Expressions" window, but after adding the appropriate code to enable the clock on EPWM2, I can see that all the parameters are being set as expected for the newly added PWM.  I can even see the counter running.

    However, the output pin isn't toggling.  I've made sure the pin is assigned to the PWM function properly.  I've also reconfigured the output to be a GPIO, and toggled it in code to prove the output is toggling on the scope.  So, I know that the scope is on the right pin, and I know that when I reconfigure the pin to be  connected to ePWM2 that the GPIO toggle code doesn't affect the output on that pin.

    I confirmed that the clock is enabled on ePWM2 by viewing it in the "Expressions" window in "SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK".

    I've run through this exercise on eWPM2A and ePWM3B.  I'm comparing parameter setups to ePWM1B, which has been working all along, but I don't see any obvious problems.  In fact, I copy/pasted from the ePWM1 setup.  Anyway, I can see in the registers that everything seems to have been setup properly.

    I've been scanning for documentation, but haven't found anything specifically related to ePWM setup on this part.

    Any more ideas?

    Thanks,

  • I'm glad that my answer helped you.

    Well, I have an idea. If you are executing the same code, that is in your first, then look carefully at AQCTL init:

       EPwm2Regs.TBPRD = period;
       EPwm2Regs.CMPB = period/2;
       EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
       EPwm2Regs.AQCTLB.bit.ZRO = AQ_SET;
       EPwm2Regs.AQCTLB.bit.CBU = AQ_CLEAR;

    You want to control EPwm2A channel, but you init AQCTLB. I think that's the problem.

  • Hi Disona,

    It's all working normally, now.

    First you led me to my mistake of not enabling the clock for each PWM, and then you enlightened me about separate action qualifier registers for A and B outputs.

    We can mark this one as answered.

    Thank you so much for your valuable assistance!

  • I'm really glad I could help =)