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.

LAUNCHXL-F28379D: Configuring ePWM interrupts

Part Number: LAUNCHXL-F28379D

asm(" SETC INTM, DBGM"); // Disable global interrupts

//--- Initialize the PIE_RAM. There are:
// 32 base vectors + (12 PIE groups * 16 vectors/group) = 224 PIE vectors (448 words).
PieCtrlRegs.PIECTRL.bit.ENPIE = 0; // Disable the PIE
asm(" EALLOW"); // Enable EALLOW protected register access

// Step around the first three 32-bit locations (six 16-bit locations).
// These locations are used by the ROM bootloader during debug.
memcpy((Uint16 *)&PieVectTable+6, (Uint16 *)&PieVectTableInit+6, 448-6);

asm(" EDIS"); // Disable EALLOW protected register access

//--- Disable all PIE interrupts
PieCtrlRegs.PIEIER1.all = 0x0000;
PieCtrlRegs.PIEIER2.all = 0x0000;
PieCtrlRegs.PIEIER3.all = 0x0001; //Enable epwm1 interrupt
PieCtrlRegs.PIEIER4.all = 0x0000;
PieCtrlRegs.PIEIER5.all = 0x0000;
PieCtrlRegs.PIEIER6.all = 0x0000;
PieCtrlRegs.PIEIER7.all = 0x0000;
PieCtrlRegs.PIEIER8.all = 0x0000;
PieCtrlRegs.PIEIER9.all = 0x0000;
PieCtrlRegs.PIEIER10.all = 0x0000;
PieCtrlRegs.PIEIER11.all = 0x0000;
PieCtrlRegs.PIEIER12.all = 0x0000;

//--- Clear any potentially pending PIEIFR flags
PieCtrlRegs.PIEIFR1.all = 0x0000;
PieCtrlRegs.PIEIFR2.all = 0x0000;
PieCtrlRegs.PIEIFR3.all = 0x0000;
PieCtrlRegs.PIEIFR4.all = 0x0000;
PieCtrlRegs.PIEIFR5.all = 0x0000;
PieCtrlRegs.PIEIFR6.all = 0x0000;
PieCtrlRegs.PIEIFR7.all = 0x0000;
PieCtrlRegs.PIEIFR8.all = 0x0000;
PieCtrlRegs.PIEIFR9.all = 0x0000;
PieCtrlRegs.PIEIFR10.all = 0x0000;
PieCtrlRegs.PIEIFR11.all = 0x0000;
PieCtrlRegs.PIEIFR12.all = 0x0000;

//--- Acknowlege all PIE interrupt groups
PieCtrlRegs.PIEACK.all = 0xFFFF;

//--- Enable the PIE
PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE
IER |= 0x0FFF; // Enable PIE Groups
asm(" CLRC INTM, DBGM");

void InitEPwm(void)
{
asm(" EALLOW"); // Enable EALLOW protected register access

// Configure the prescaler to the ePWM modules. Max ePWM input clock is 100 MHz.
ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV = 1; // EPWMCLK divider from PLLSYSCLK. 0=/1, 1=/2

// Must disable the clock to the ePWM modules if you want all ePWM modules synchronized.
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;

asm(" EDIS"); // Disable EALLOW protected register access


//---------------------------------------------------------------------
//--- Configure ePWM2 to trigger ADC SOCA at a 50 kHz rate
//---------------------------------------------------------------------
asm(" EALLOW"); // Enable EALLOW protected register access
DevCfgRegs.SOFTPRES2.bit.EPWM1 = 1; // ePWM1 is reset
DevCfgRegs.SOFTPRES2.bit.EPWM1 = 0; // ePWM1 is released from reset
asm(" EDIS"); // Disable EALLOW protected register access

EPwm1Regs.TBCTL.bit.CTRMODE = 0x3; // Disable the timer

EPwm1Regs.TBCTL.all = 0xC033; // Configure timer control register
// bit 15-14 11: FREE/SOFT, 11 = ignore emulation suspend
// bit 13 0: PHSDIR, 0 = count down after sync event
// bit 12-10 000: CLKDIV, 000 => TBCLK = HSPCLK/1
// bit 9-7 000: HSPCLKDIV, 000 => HSPCLK = EPWMCLK/1
// bit 6 0: SWFSYNC, 0 = no software sync produced
// bit 5-4 11: SYNCOSEL, 11 = sync-out disabled
// bit 3 0: PRDLD, 0 = reload PRD on counter=0
// bit 2 0: PHSEN, 0 = phase control disabled
// bit 1-0 11: CTRMODE, 11 = timer stopped (disabled)

EPwm1Regs.TBCTR = 0x0000; // Clear timer counter
EPwm1Regs.TBPRD = ISR_Freq_TBPRD; // Set timer period
EPwm1Regs.TBPHS.bit.TBPHS = 0x0000; // Set timer phase

EPwm1Regs.ETPS.all = 0x0101; // Configure SOCA
// bit 15-14 00: EPWMxSOCB, read-only
// bit 13-12 00: SOCBPRD, don't care
// bit 11-10 00: EPWMxSOCA, read-only
// bit 9-8 01: SOCAPRD, 01 = generate SOCA on first event
// bit 7-4 0000: reserved
// bit 3-2 00: INTCNT, don't care
// bit 1-0 01: INTPRD, generate interrupt on first event

EPwm1Regs.ETSEL.all = 0x0A0B; // Enable SOCA to ADC, Enable interrupt on CTR=0 & CTR=PRD
// bit 15 0: SOCBEN, 0 = disable SOCB
// bit 14-12 000: SOCBSEL, don't care
// bit 11 1: SOCAEN, 1 = enable SOCA
// bit 10-8 010: SOCASEL, 010 = SOCA on PRD event
// bit 7-4 0000: reserved
// bit 3 1: INTEN, 1 = Enable interrupt
// bit 2-0 011: INTSEL, CTR=0 or PRD
// EPwm1Regs.ETSEL.bit.INTEN = 0x1;
// EPwm1Regs.ETSEL.bit.INTSEL = 0x3;
EPwm1Regs.TBCTL.bit.CTRMODE = 0x2; // Enable the timer in count up-down mode


//---------------------------------------------------------------------
//--- Enable the clocks to the ePWM module.
//--- Note: this should be done after all ePWM modules are configured
//--- to ensure synchronization between the ePWM modules.
//---------------------------------------------------------------------
asm(" EALLOW"); // Enable EALLOW protected register access
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1; // TBCLK to ePWM modules enabled
asm(" EDIS"); // Disable EALLOW protected register access

} // end InitEPwm()

I tried above code (write as two different functions and called in the main function) in order to generate ePWM1 interrupt. But I found that respective interrupt flag is not set when the interrupt occurs and i couldn't be able to find the mistake that I've made.

Please help to find the mistake. Ambition is to generate 20 kHz ISR

Thank You

Lahiru

  • I’ll take a look at this.

  • Hi Nima,

    Thank you very much 

    Lahiru

  • Below is a 20KHz EPWM with interrupts.

    //
    // Included Files
    //
    #include "F28x_Project.h"
    
    //
    // Defines
    //
    #define EPWM1_TIMER_TBPRD  1250  // Period register
    
    
    //
    // Function Prototypes
    //
    void InitEPwm1Example(void);
    __interrupt void epwm1_isr(void);
    
    //
    // Main
    //
    void main(void)
    {
    //
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2837xD_SysCtrl.c file.
    //
        InitSysCtrl();
    
    //
    // Step 2. Initialize GPIO:
    // This example function is found in the F2837xD_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    //
    //    InitGpio();
    
    //
    // enable PWM1, PWM2 and PWM3
    //
        CpuSysRegs.PCLKCR2.bit.EPWM1=1;
    
    //
    // For this case just init GPIO pins for ePWM1, ePWM2, ePWM3
    // These functions are in the F2837xD_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 F2837xD_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 F2837xD_DefaultIsr.c.
    // This function is found in F2837xD_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.EPWM1_INT = &epwm1_isr;
        EDIS;   // This is needed to disable write to EALLOW protected registers
    
    //
    // For this example, only initialize the ePWM
    //
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
        EDIS;
    
        InitEPwm1Example();
    
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
        EDIS;
    
    //
    // Step 4. User specific code, enable interrupts:
    //
    
    //
    // Enable CPU INT3 which is connected to EPWM1-3 INT:
    //
        IER |= M_INT3;
    
    //
    // Enable EPWM INTn in the PIE: Group 3 interrupt 1-3
    //
        PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
    
    //
    // Enable global Interrupts and higher priority real-time debug events:
    //
        EINT;  // Enable Global interrupt INTM
        ERTM;  // Enable Global realtime interrupt DBGM
    
    //
    // Step 5. IDLE loop. Just sit and loop forever (optional):
    //
        for(;;)
        {
            asm ("    NOP");
        }
    }
    
    //
    // epwm1_isr - EPWM1 ISR
    //
    __interrupt void epwm1_isr(void)
    {
    
        //
        // Clear INT flag for this timer
        //
        EPwm1Regs.ETCLR.bit.INT = 1;
    
        //
        // Acknowledge this interrupt to receive more interrupts from group 3
        //
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
    }
    
    //
    // InitEPwm1Example - Initialize EPWM1 configuration
    //
    void InitEPwm1Example()
    {
        //
        // Setup TBCLK
        //
        EPwm1Regs.TBPRD = EPWM1_TIMER_TBPRD;       // Set timer period 801 TBCLKs
        EPwm1Regs.TBPHS.bit.TBPHS = 0x0000;        // Phase is 0
        EPwm1Regs.TBCTR = 0x0000;                  // Clear counter
    
        //
        // Set Compare values
        //
        EPwm1Regs.CMPA.bit.CMPA = EPWM1_TIMER_TBPRD/2;    // Set compare A value
        EPwm1Regs.CMPB.bit.CMPB = EPWM1_TIMER_TBPRD/2;    // Set Compare B value
    
        //
        // Setup counter mode
        //
        EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up and down
        EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // Disable phase loading
        EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
        EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    
        //
        // Setup shadowing
        //
        EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
        EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
        EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // Load on Zero
        EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
        //
        // Set actions
        //
        EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;            // Set PWM1A on event A, up
                                                      // count
        EPwm1Regs.AQCTLA.bit.PRD = AQ_CLEAR;          // Clear PWM1A on event A,
                                                      // down count
    
        EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET;            // Set PWM1A on event A, up
                                                      // count
        EPwm1Regs.AQCTLB.bit.PRD = AQ_CLEAR;          // Clear PWM1A on event A,
                                                      // down count
    
        //
        // Interrupt where we will change the Compare Values
        //
        EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
        EPwm1Regs.ETSEL.bit.INTEN = 1;                // Enable INT
        EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;           // Generate INT on 3rd event
    
    }
    
    //
    // End of file
    //
    

    The clock is set to 200MHz.