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/TMS320F28379D: EPWM register bit fields are not being set

Part Number: TMS320F28379D

Tool/software: Code Composer Studio

Most of the time, when I press debug and watch the registers, I notice that even though my code may explicitly set the epwm period to be 5000 counts, the register will not update and just say 0. Or sometimes it'll be the phase that doesn't get set or both. Sometimes, the CMPA will also not set.

Is there something wrong with my InitEPwm code? I do call InitEPwm() and InitEPwmGpio() in the main function.

void InitEPwm2(void)
{
    EALLOW;
    // Setup TBCLK
    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;                       // Count up
    EPwm2Regs.TBPRD = PWM5_PERIOD ;                         // Same period as PWM5
    EPwm2Regs.TBCTL.bit.PHSEN = 1;                         // Enable phase loading
    EPwm2Regs.TBPHS.bit.TBPHS = 500;                     // Phase
    EPwm2Regs.TBCTR = 0x0000;                    // Clear counter
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = 1;           // Clock ratio to SYSCLKOUT
    EPwm2Regs.TBCTL.bit.CLKDIV = 0;
    EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;            // SYNC output on CTR = 0


    // Setup shadow register load on ZERO
    EPwm2Regs.CMPCTL.bit.SHDWAMODE = 0;
    EPwm2Regs.CMPCTL.bit.SHDWBMODE = 0;
    EPwm2Regs.CMPCTL.bit.LOADAMODE = 0;
    EPwm2Regs.CMPCTL.bit.LOADBMODE = 0;

    // Set Compare values
    EPwm2Regs.CMPA.bit.CMPA = dutyCycle ;        // Set compare A value

    // Set actions
    EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;                // Set PWM2A on Zero
    EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;                // Clear PWM2A on event A, up count

    EDIS;
}

  • Can you share the CCS project I would like to see the setup code before InitPWM

  • #include "F28x_Project.h"
    
    //functions
    void ConfigureADC(void);
    void SetupADCEpwm(void);
    void ConfigureEPWM(void);
    void InitEPwm2(void);
    void InitEPwm3(void);
    interrupt void adca1_isr(void);
    
    //variables
    #define PWM5_PERIOD	5000
    #define ADC_PERIOD  2000
    Uint16 m1;
    int flag = 0 ;
    Uint16 phase = 2500;
    Uint16 dutyCycle = 2500 ;
    Uint16 m1 = 0;
    
    
    int main(void) {
    	
    // Initialize System Control
    	InitSysCtrl();
    	EALLOW;
    	ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV = 1;
    	EDIS;
    
    // Enable PWM1 and PWM5
    	CpuSysRegs.PCLKCR2.bit.EPWM1=1;
    	CpuSysRegs.PCLKCR2.bit.EPWM2=1;
    	CpuSysRegs.PCLKCR2.bit.EPWM3=1;
    	CpuSysRegs.PCLKCR2.bit.EPWM6=1;
    	CpuSysRegs.PCLKCR2.bit.EPWM5=1;
    
    // Initialize GPIO
    	InitGpio(); 							// Configure default GPIO
    	InitEPwm6Gpio();
    	InitEPwm5Gpio();	                    // Configure EPWM5 GPIO pins
    	InitEPwm2Gpio();                        // Configure EPWM5 GPIO pins
    	InitEPwm1Gpio();
    
    	EALLOW;
        DevCfgRegs.CPUSEL0.bit.EPWM5 = 0x1;    //transfer epwm5 to cpu2
        DevCfgRegs.CPUSEL0.bit.EPWM6 = 0x1;    //transfer epwm6 to cpu2
        EDIS;
    
    	EALLOW;
    	GpioCtrlRegs.GPADIR.bit.GPIO18 = 1;			// enable gpio18 as output
    	EDIS;
    	GpioDataRegs.GPACLEAR.bit.GPIO18 = 1;			// force low
    
    
    // Clear all interrupts, initialize PIE control registers and vector table
    	DINT;
    	InitPieCtrl();
    	IER = 0x0000;
    	IFR = 0x0000;
    	InitPieVectTable();
    
    
    	// Enable PIE interrupts
        PieCtrlRegs.PIEIER1.bit.INTx1 = 1;      // ADC ISR
        PieCtrlRegs.PIEIER1.bit.INTx13 = 1;     // IPC1 ISR
    
    
    // Map ISR functions
    	EALLOW;
    	PieVectTable.ADCA1_INT = &adca1_isr; 	// ADCA1 interrupt
    	EDIS;
    
    // Start ADC and EPWM
    	ConfigureADC();
    	ConfigureEPWM();
    	SetupADCEpwm();
    
    	InitEPwm3();
    	InitEPwm2();
    
    //Clear IPC flags
    	IpcRegs.IPCCLR.all = 0xFFFFFFFF;
    	InitIpc() ;
    
    // Enable global interrupts and higher priority real-time debug events:
    	IER |= M_INT1; 						// Enable group 1 interrupts
    	EINT;  								// Enable Global interrupt INTM
    	ERTM;  								// Enable Global realtime interrupt DBGM
    
    // Enable PIE interrupts
    	PieCtrlRegs.PIEIER1.bit.INTx1 = 1;	    // ADC ISR
        PieCtrlRegs.PIEIER1.bit.INTx13 = 1;     // IPC1 ISR
    
    // Wait here until CPU02 is ready
        while (IpcRegs.IPCSTS.bit.IPC17 == 0) ; // Wait for CPU02 to set IPC17
        IpcRegs.IPCACK.bit.IPC17 = 1;           // Acknowledge and clear IPC17
    
    // Sync ePWM
        EALLOW;
    	CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    
    // Start ePWM
    	EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; 			// Un-freeze and enter up-count mode
    
    	while(1)
    	{
    		;
    	}
    }
    
    
    void ConfigureADC(void)
    {
    	EALLOW;
    	AdcaRegs.ADCCTL2.bit.PRESCALE = 6; 			// Set ADCCLK divider to /4
    	AdcaRegs.ADCCTL2.bit.RESOLUTION =  0; 		// 12-bit resolution
    	AdcaRegs.ADCCTL2.bit.SIGNALMODE = 0; 		// Single-ended channel conversions (12-bit mode only)
    	AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;		// Set pulse positions to late
    	AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;			// Power up the ADC
    	EDIS;
    
    	DELAY_US(1000);								// Delay for 1ms to allow ADC time to power up
    }
    
    void ConfigureEPWM(void)
    {
    	EALLOW;
    	// Assumes ePWM clock is already enabled
    	EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;            // Freeze counter
    	EPwm1Regs.TBCTL.bit.CLKDIV = 0;
    	EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1;          // TBCLK pre-scaler = /1
    	/*
    	EPwm1Regs.ETSEL.bit.SOCAEN  = 0;            // Disable SOC on A group
    
    	EPwm1Regs.TBCTR = 0x0000;                    // Clear counter
    	EPwm1Regs.ETSEL.bit.SOCASEL = 1;            // Enable TBCTR = 0
    	EPwm1Regs.ETSEL.bit.SOCAEN = 1;             // Enable SOCA
    	EPwm1Regs.ETPS.bit.SOCAPRD = 1;             // Generate pulse on 1st event
    	EDIS;
    	*/
    
    	EALLOW;
    	EPwm1Regs.TBPRD = PWM5_PERIOD ;
    	EPwm1Regs.TBCTL.bit.PHSEN = 1 ;
    	EPwm1Regs.TBPHS.bit.TBPHS = 0 ;
    	EPwm1Regs.TBCTR = 0x0000 ;
    	EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO ;
    
    	// Setup shadow register load on ZERO
        EPwm1Regs.CMPCTL.bit.SHDWAMODE = 0;
        EPwm1Regs.CMPCTL.bit.SHDWBMODE = 0;
        EPwm1Regs.CMPCTL.bit.LOADAMODE = 0;
        EPwm1Regs.CMPCTL.bit.LOADBMODE = 0;
    
        // Set Compare values
        EPwm1Regs.CMPA.bit.CMPA = dutyCycle ;        // Set compare A value
    
        // Set actions
        EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;                // Set PWM5A on Zero
        EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;                // Clear PWM5A on event A, up count
    
        EDIS;
    
    }
    
    void InitEPwm2(void)
    {
        EALLOW;
        // Setup TBCLK
        EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;                       // Count up
        EPwm2Regs.TBPRD = PWM5_PERIOD ;                         // Same period as PWM5
        EPwm2Regs.TBCTL.bit.PHSEN = 1;                         // Enable phase loading
        EPwm2Regs.TBPHS.bit.TBPHS = 500;                     // Phase
        EPwm2Regs.TBCTR = 0x0000;                    // Clear counter
        EPwm2Regs.TBCTL.bit.HSPCLKDIV = 1;           // Clock ratio to SYSCLKOUT
        EPwm2Regs.TBCTL.bit.CLKDIV = 0;
        EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;            // SYNC output on CTR = 0
    
    
        // Setup shadow register load on ZERO
        EPwm2Regs.CMPCTL.bit.SHDWAMODE = 0;
        EPwm2Regs.CMPCTL.bit.SHDWBMODE = 0;
        EPwm2Regs.CMPCTL.bit.LOADAMODE = 0;
        EPwm2Regs.CMPCTL.bit.LOADBMODE = 0;
    
        // Set Compare values
        EPwm2Regs.CMPA.bit.CMPA = dutyCycle ;        // Set compare A value
    
        // Set actions
        EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;                // Set PWM5A on Zero
        EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;                // Clear PWM5A on event A, up count
    
        EDIS;
    }
    
    void InitEPwm3(void)
    {
        EALLOW;
        EPwm3Regs.TBCTL.bit.CTRMODE = 3;            // Freeze counter
        EPwm3Regs.TBCTL.bit.CLKDIV = 0;
        EPwm3Regs.TBCTL.bit.HSPCLKDIV = 0;          // TBCLK pre-scaler = /1
        EPwm3Regs.TBPRD = 2000;               // Set period to 2000 counts (50kHz)
        EPwm3Regs.ETSEL.bit.SOCAEN  = 0;            // Disable SOC on A group
    
        EPwm3Regs.TBCTR = 0x0000;                    // Clear counter
        EPwm3Regs.ETSEL.bit.SOCASEL = 0x1;            // Enable TBCTR = 0
        EPwm3Regs.ETSEL.bit.SOCAEN = 1;             // Enable SOCA
        EPwm3Regs.ETPS.bit.SOCAPRD = 1;             // Generate pulse on 1st event
        EDIS;
    }
    
    void SetupADCEpwm(void)
    {
    	// Select the channels to convert and end of conversion flag
    	EALLOW;
    	AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0;  		// SOC0 will convert pin A0
    	AdcaRegs.ADCSOC0CTL.bit.ACQPS = 14; 		// Sample window is 100 SYSCLK cycles
    	AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 9; 		// Trigger on ePWM3 SOCA/C
    	AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; 		// End of SOC0 will set INT1 flag
    	AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;   		// Enable INT1 flag
    	AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; 		// Make sure INT1 flag is cleared
    	EDIS;
    }
    
    
    interrupt void adca1_isr(void)
    {
    	flag = 1 ;
    	GpioDataRegs.GPATOGGLE.bit.GPIO18 = 1;
    	// Read the ADC result and store in m1
    	m1 = AdcaResultRegs.ADCRESULT0;
    	//can't send temporary variables on cpu1 over to cpu2 (ex. m1)
    	IpcRegs.IPCSENDDATA = AdcaResultRegs.ADCRESULT0 ;
    
    	IpcRegs.IPCSET.bit.IPC1 = (unsigned int) 1 ;
    
    	// Return from interrupt
    	AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; 		// Clear ADC INT1 flag
    	PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;		// Acknowledge PIE group 1 to enable further interrupts
    	GpioDataRegs.GPATOGGLE.bit.GPIO18 = 1;
    }
    
    
    

    Also currently, strangely my epwm2 is working now. However, my epwm3 also still doesn't work in that it doesn't set the period or SOCASEL.

  • e2e_field_gets_set.zip

    Christine,

    I just ran your code and single stepped through it. All registers get updated with the values you have set. Maybe this is a setup issue. I have attached the CCS project to this. Please run this, place a break point after the function containing the last EPWM config code, and check all the values in the register view.

  • thank you for the help!