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 using IQMath

Other Parts Discussed in Thread: CONTROLSUITE

I'm currently working with a Piccolo ControlSTICK to get a sin-waveform out of the ePWM module using IQmath, but it`s my first microcontroller.

Anyone kwons how to configure a ePWM module and the interruptions?

Follow my code below:

#include "DSP2802x_Device.h"         // DSP2802x Headerfile
#include "DSP2802x_Examples.h"       // DSP2802x Examples Headerfile
#include "DSP2802x_EPwm_defines.h"     // useful defines for initialization
#include "IQmathLib.h"
#include "math.h"
#include "PeripheralHeaderIncludes.h"


#define Buffer_size 512

//--------------------------------------------------------------
// Declare your function prototypes here
//---------------------------------------------------------------

void ePWM1_Config(int);

interrupt void cpu_timer0_isr(void);


Uint32 width;
Uint16 frac;
Uint16 CMPALR;

// General System nets - Useful for debug
Uint16 i,j,    DutyFine, n,update;
Uint32 temp;

int16 signal8;
int16 signal4;
int16 signal2;
int16 signalT[Buffer_size];

_iq26 in2;
_iq26 in4;
_iq26 in8;

void main(void)
{   

// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP2802x_SysCtrl.c file.
   InitSysCtrl();

// Step 2. Initalize GPIO:
// This example function is found in the DSP2802x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio();  // Skipped for this example
// For this case, just init GPIO for EPwm1-EPwm4

// For this case just init GPIO pins for EPwm1, EPwm2, EPwm3, EPwm4
// These functions are in the DSP2802x_EPwm.c file
   InitEPwm1Gpio();

// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
   DINT;

// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the DSP2802x_PieCtrl.c file.
   InitPieCtrl();

// Disable CPU interrupts and clear all CPU interrupt flags:
   IER = 0x0000;
   IFR = 0x0000;

// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example.  This is useful for debug purposes.
// The shell ISR routines are found in DSP2802x_DefaultIsr.c.
// This function is found in DSP2802x_PieVect.c.
  InitPieVectTable();

// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
   EALLOW;  // This is needed to write to EALLOW protected registers
   PieVectTable.TINT0 = &cpu_timer0_isr;
   EDIS;    // This is needed to disable write to EALLOW protected registers

// Step 4. Initialize the Device Peripheral. This function can be
//         found in DSP2802x_CpuTimers.c
   InitCpuTimers();   // For this example, only initialize the Cpu Timers

   ConfigCpuTimer(&CpuTimer0, 60, 64*32.5520833);

  // To ensure precise timing, use write-only instructions to write to the entire register. Therefore, if any
// of the configuration bits are changed in ConfigCpuTimer and InitCpuTimers (in DSP2802x_CpuTimers.h), the
// below settings must also be updated.

   CpuTimer0Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0
   //CpuTimer1Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0
  // CpuTimer2Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0

// Step 5. User specific code, enable interrupts:
// Enable CPU int1 which is connected to CPU-Timer 0, CPU int13
// which is connected to CPU-Timer 1, and CPU int 14, which is connected
// to CPU-Timer 2:
   IER |= M_INT1;
   //IER |= M_INT13;
   //IER |= M_INT14;

// Enable TINT0 in the PIE: Group 1 interrupt 7
   PieCtrlRegs.PIEIER1.bit.INTx7 = 1;

// Enable global Interrupts and higher priority real-time debug events:
   EINT;   // Enable Global interrupt INTM
   ERTM;   // Enable Global realtime interrupt DBGM

// Step 4. Initialize all the Device Peripherals:
// This function is found in DSP2802x_InitPeripherals.c
// InitPeripherals();  // Not required for this example

// For this example, only initialize the EPwm
// Step 5. User specific code, enable interrupts:

   update =1;
   DutyFine =0;

   EALLOW;
   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
   EDIS;

//====================================================================
// ePWM register initializaition
//====================================================================
 
   ePWM1_Config(10);        // ePWM1 target, Period = 10

   EALLOW;
   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
   EDIS;

   while (update ==1)

    {

for(i=0; i < 512; i++)
            {
                in8 = _IQ26(0.01227184*i);
                in8=_IQ26sin(in8) ;
                signal8= _IQtoQ11(in8);

                in4 = _IQ26(0.01227184*2*i);
                in4=_IQ26sin(in4) ;
                signal4= _IQtoQ11(in4);
       
                in2 = _IQ26(0.01227184*4*i);
                in2=_IQ26sin(in2) ;
                signal2= _IQtoQ11(in2);

              signalT[i] = signal8 + signal4 + signal2;
            }


void ePWM1_Config(period)
{

    EPwm1Regs.TBCTL.bit.PRDLD = TB_IMMEDIATE;            // set Immediate load
    EPwm1Regs.TBPRD = period;                            // PWM frequency = 1 / period
    EPwm1Regs.CMPA.half.CMPA = period / 2;              // set duty 50% initially
    EPwm1Regs.CMPB = period / 2;                        // set duty 50% initially
    EPwm1Regs.TBPHS.all = 0;
    EPwm1Regs.TBCTR = 0;

    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
    EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;               // EPwm1 is the Master
    EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
    EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;

    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;

    EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; //AQ_CLEAR;               // PWM toggle low/high
    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;//AQ_SET;
    EPwm1Regs.AQCTLB.bit.ZRO = AQ_CLEAR;
    EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;

}

interrupt void cpu_timer0_isr(void)
{
   CpuTimer0.InterruptCount++;
            if (i>=512)
            {
                i=0;
            }
            else
            {
            EPwm1Regs.CMPA.half.CMPA = signalT[i];
            i++;
            }
   
    // Enable more interrupts from this timer   
    EPwm1Regs.ETCLR.bit.INT = 1;        
         

   //adc_result = AdcResult.ADCRESULT0;
   // Acknowledge this interrupt to receive more interrupts from group 1
   PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

}

Best Regards

Gustavo Rodrigues

  • Hello - This is a generic question and a huge topic. My suggestion for you is to go through the example projects available with header file installation. However, recently TI has changed their software deployment vehicle and starting using Control Suite - I am not sure if example projects are still with header file installation or not - please check or call TI hotline. These example projects deal with individual peripherals including PWM module and are excellent to know in deatil about these devices and peripherals. You can also try to attend TI training sessions both online and in live classes. Good luck.

  • Arefeen -

    The header file examples are still available in the controlSUITE installation under device_support (included with the headers). Note, these examples are only available for CCSv4.x.  If users are on CCSv3.3, the legacy software downloads should still be available on the web.