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.

Piccolo PWM

Hi all,

I'm currently working with a Piccolo ControlSTICK to get a sin-waveform out of the ePWM module via a lowpass filter.

Because this is my first microcontroller I'm programming I'm not used to the techniques. I'm stuck with setting up an interupt to change the compare value. My thought was to change the CMPA register every overflow of the TBCTR but I can't find a hint on how to do this.

Just putting this code

for(i=0;;i+=1)
    {
      EPwm1Regs.CMPA.half.CMPA = sinus1[i];      // set compare value
      i = i%128;                                 // modulo to endlessly loop after one period

    }

in the runtime section doesn't change CMPA every PWM cycle but every now and then even before one cycle is completed. So I'm looking for help on how to make this code to work after one TBCTR overflow.

 

Many thanks,

Mario

  • Hello Mario

    I am not familiar with the exact technique utilized in control stick but there are various ways to generate sine waveform and many of those technqiues utilize lookup table to minimize cycle counts. As you mentioned the compare value is modified using a sine lookup table value and this update can be done every PWM cycle by generating a PWM interrupt at every period or at every instant when counter is zero.

    If you are new to these techniques on how to generate different waveforms using a C2000 device (including Piccolo) then one excellent reference could be C28x Signal Generator Library (SPRC083).

     

  • Hello again.

     

    I managed to get my PWM working. Now I'm using all 4 PWM modules and an ISR for each to load the next compare value from a sine table consisting of 256 uint16 values.

    Everything works fine as long as I run the code from RAM, but when I try to run from FLASH it fails.

    I used the instructions in spraal3.pdf and the C28x1DayWorkshop.pdf to program the FLASH and everything wents through the compiler, linker etc. without any errors.

    Stepwise execution showed that it seems that no ISRs are worked through. So either no interupt was generated or the code was simply not executed.

     

    I used the example code AsymmetricPWM and modified it to use interupts and all 4 modules.

    I don't know how to fix this and any help would be appreciated. If there is a specific section of code I need to post, please let me know which one, because posting the whole program would be lengthy.

     

    Many thanks,

     

    Mario

  • Mario -

    Time critical code (such as ISR's) must be copied into RAM from FLASH.  To do this, follow the flash example in the header files and peripheral examples software package.

    i.e. at the top of your code, add:

    #pragma CODE_SECTION(epwm1_timer_isr, "ramfuncs"); // where epwm1_timer_isr is replaced with your isr name.

    Declare extern variables (defined in linker):

    // These are defined by the linker
    extern Uint16 RamfuncsLoadStart;
    extern Uint16 RamfuncsLoadEnd;
    extern Uint16 RamfuncsRunStart;

    In code, before calling "InitFlash()", call the following function:

     MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);

     

     

  • Thanks for the reply.

     

    I've add this #pragma section and further examination showed interupts are generated and the ISR code is worked through, but it still doesn't work.

     

    This is my ISR code:

    interrupt void ISR1(void)
    {
        EPwm1Regs.CMPA.half.CMPA = sine1[loop1];       // Set new compare value
           EPwm1Regs.CMPB = sine1[(2*loop1)%256];             // Channel B with doubled frequency
        loop1++;
        loop1 = loop1%256;                               // Modulo to endlessly cycle through table
       
        // Enable more interrupts from this timer
        EPwm1Regs.ETCLR.bit.INT = 1;
        // Acknowledge interrupt to recieve more interrupts from PIE group 3
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
    }

    sine1 is an array, consisting of 256 Uint16 values declared and initialised as const at the top of my code and represents my sine lookup table.

    loop1 is a global int, controlling the position in the lookup table. It should increase everytime an ISR is worked through, but that doesn't happen. My guess is that variables (loop1 here) can't get changed because they are written in the FLASH section and don't get copied to RAM were they can get modified.

    Could that be the problem and if so, how implement the copying?

     

    Best regards,

    Mario

  • Mario -

    Are you using the F28027.cmd command linker file for your flash project? (linker file used by the flash examples in the header files and peripheral examples package)?

    Basically, your global variables that change need to be mapped to RAM as well. So if you look in the command linker file, notice that  under "SECTIONS" the ".ebss" (for global variables) section is mapped to RAM (designated in PAGE 1 data memory).  If you are not using the F28027.cmd generic command linker file, be sure to map your .ebss section to RAM memory and not flash.

     .ebss               : > RAML2       PAGE = 1

  • Thanks again.

     

    That got me to the right point. .ebss was mapped to dataRAM, which is not accessable for user programms (section in memory map is called Peripheral Frame 0 according to http://focus.ti.com/lit/ds/symlink/tms320f28027.pdf). Now I mapped it to M1 SARAM and everthing works fine.

    Thanks again for the help and a great weekend to all.

     

    Mario

  • Hi,

    I am new to TI microcontrollers in general.

    I'm currently working with a Piccolo ControlSTICK to get a sin-waveform out of the ePWM module via a lowpass filter too.

    Could you explain or send me your code so I can study it.

    Thanks in advance regards

    Gustavo Rodrigues

     o_gusa@hotmail.com