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/TMS320F28069: Program does not run when I update PWM1

Part Number: TMS320F28069
Other Parts Discussed in Thread: LAUNCHXL-F28069M

Tool/software: Code Composer Studio

Hi,

I am working with board LAUNCHXL-F28069M.

The aim of my program is to generate two sinusoidal waveforms for a power converter. For that, I am using PWM1 and PWM2. Both PWM are configured in the exact same way.

Since the output is a sinusoidal waveform, duty cycle must vary continuously. At the current stage of the development, I am trying to get the same output in both PWMs. In order to do so, I update PWM as:

EPwm1Regs.CMPA.half.CMPA = EPwm1Regs.TBPRD * duty;

EPwm2Regs.CMPA.half.CMPA = EPwm2Regs.TBPRD * duty;

I always make sure that duty is between 0 and 1 prior to the update. Duty is defined as float.

Here is my problem:

 

-If duty is a constant value or is varied manually by me as an expression, everything works correctly.

-If duty is varied following a sinusoidal pattern, program compiles but does not run.

-If I fix the duty for PWM1 to a constant value and I let it vary for PWM2, it compiles and runs. This does not work the other way around (fixing PWM2 and varying PWM1).

 

Any clue on what could be happening?

 

Best Regards.

  • Just wanted to add, I am using Code Composer Version: 7.4.0.00015 and compiler version TI v18.9.0.ST.

    Best Regards.
  • Cristina,

         Thanks for explaining your issue well and providing some initial debug!

    • Where are you updating your CMPA values in your code? The best place to do this will be in your PWM ISR.
      • Secondly, if you are updating the PWM in the ISR, how is your ISR configured?
    • When you say the program does not run, what happens?

    We will have to debug this a bit more...

    1. Does the code load onto the device?
    2. How is the device failing? ...does it halt, does it execute the wrong code, does the PWM output anything?
    3. Have you verified your configurations using the memory browser?
    4. Are you using EALLOW before writing to EALLOW protected registers?

    Regards,
    Cody

  • Hi, thanks for the answer.

    I use ePWM1 to generate a periodic ADC SOC - ADCINT1, so I update the CMPA value at the end of the ADC interrupt, just before clearing the flag. I do this because later I will need to read some sensor through the ADC. This is the ADC configuration: 

    AdcRegs.ADCCTL2.bit.ADCNONOVERLAP = 1;	       // Enable non-overlap mode
    AdcRegs.ADCCTL1.bit.INTPULSEPOS	= 1;	               // ADCINT1 trips after AdcResults latch
    
    AdcRegs.INTSEL1N2.bit.INT1E     = 1;	                       // Enabled ADCINT1
    AdcRegs.INTSEL1N2.bit.INT1CONT  = 0;	               // Disable ADCINT1 Continuous mode
    AdcRegs.INTSEL1N2.bit.INT1SEL 	= 1;                 // setup EOC1 to trigger ADCINT1 to fire
    
    AdcRegs.ADCCTL1.bit.ADCREFSEL = 0;                    //Select internal reference mode
    AdcRegs.ADCCTL1.bit.VREFLOCONV = 1;                 //Select VREFLO internal connection on B5

    This is how I know it is not running: Whenever I run a CCS program I put some expressions to watch and enable continuous refresh, so I know the program is running just visually because I see yellow updates. Also, I have one LED in the PCB that is just turned on dummy in the main and is not doing so. Lastly, I check with the oscilloscope and I don't have any PWM output. 

    Regarding the rest of the questions:

    1. I am not sure how to check if it is really loading onto the device.

    2. I already answered this above.

    3. Again, I am not sure how to verify the configurations using the memory browser.

    4. I have some initialization functions and just to be sure I write EALLOW at the beginning of each one. I belive CMPA is not protected, but just in case I tried writing EALLOW before updating and nothing changed.

    Best regards.

  • Cristina,

    take a look at the following help document, it should guide you on how you can use the tools (breakpoints, single stepping, and the memory browser) to help find out where the problem is.

    Regards,
    Cody 

  • Thanks for the information,

    I didn't think of using the breakpoints because I assumed the program was not even loading, but that is not correct. Now I am even more confused than before.

    I added a break point in the main, just before the while(1){}. I turn a LED on just before this loop and is turning on. Sadly, if after that I go step by step the pointer gets stack in the while(1) and no matter how many times I press step into it doesn't move. Step over does not work also. It is like the interruption is not taking place, but it does not make sense since the only thing that changes between two codes is what value I try to add to CMPA, and that is something that happens after some lines of code in the interruption.

    Regards,

    Cristina.
  • Cristina,
    set a breakpoint in each of the interrupts, then run the code. If it executes the interrupt it should halt the program counter.

    Then run it again and see if it ever enters the interrupt again. If it does not enter the interrupt again you may want to check if you correctly have acknowledged the interrupts.

    Regards,
    Cody
  • Hi,

    There is only one interrupt in my program, the ADC one. I set a breakpoint there and it is getting inside the interruption 5 times. Then it stops entering. This is how I acknowledged the interruptions:

           // Reinitialize for next ADC sequence

           AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;           //Clear ADCINT1 flag reinitialize for next SOC

           PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;         // Acknowledge interrupt to PIE

     

    I have the problem isolated in the update of the CMPA register for PWM1, and no matter how much I simplify the code it won't do it correctly.

    Is there a possibility of a bug somehow? Because I tried also this in the interruption:

    pwm_aux = EPwm1Regs.TBPRD;

    aux1 = pwm_aux * Du;

    aux2 = aux1;

    EPwm1Regs.CMPA.half.CMPA = aux2;

    And defined as global variables:

    float Du = 0.0;

    unsigned int pwm_aux = 0;

    float aux1 = 0.0;

    unsigned int aux2 = 0.0;

      

    Well, if I define aux2 as unsigned int the code does not run more than those 5 times. When I define aux2 as int it runs "forever", but obviously the result is not correct because of the sign.

    Thanks for the effort on trying to help me.

  • Hi,

    So I managed to kind of solve the problem.

    I was limiting my duty cycle between 0.0 and 1.0, and the program was getting corrupted when duty reached 1.0. In order to solve it, I now limit it between 0.0 and 0.99.

    Although this makes the code work fine, still does not answer why the issue affected only PWM1 and not PWM2.

    Best regards and thanks for the help.