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/TMS320F28335: Issues with variable pulse width!

Part Number: TMS320F28335
Other Parts Discussed in Thread: CONTROLSUITE, C2000WARE

Tool/software: Code Composer Studio

Hello,
I have been trying to program my eZdsp f28335 to give a variable pulse width based on analogue voltage input but it is not working.
I am using both epwm1a and adc interrupt. I am using the epwm to trigger a start of conversion in adc. I am using the adc isr to extract digital value which epwm isr sets as CMPA.
It is however not giving me the expected result. I am only stuck at 100% duty cycle which is the initial condition when CMPA = 0 for the up-down count which I am using. It seems as if the adc isr is hardly called.
Any ideas/tips will be much appreciated. I have attached the code herewith.... I use ccsv3.3...
Thanks in advance.
David.



#include "DSP2833x_Device.h" 

extern void InitSysCtrl(void);
extern void InitPieCtrl(void);
extern void InitPieVectTable(void);
extern void InitCpuTimers(void);
extern void InitAdc(void);
extern void ConfigCpuTimer(struct CPUTIMER_VARS *, float, float);

void Setup_GPIO(void);
void Setup_ePWM1A(void);
void Setup_adc(void);
interrupt void CpuTimer0_isr(void);
interrupt void adc_isr(void);
interrupt void ePWM_isr(void);
unsigned int Voltage_VR1;
void main()
{
	InitSysCtrl();
	EALLOW;
	SysCtrlRegs.WDCR = 0x00AF;
	EDIS;
	DINT;
	Setup_GPIO();
	InitPieCtrl();
	InitPieVectTable();
	InitAdc();
	Setup_adc();
	Setup_ePWM1A();
	EALLOW;
	PieVectTable.TINT0 = &CpuTimer0_isr;
	PieVectTable.ADCINT = &adc_isr;
	PieVectTable.EPWM1_INT = &ePWM_isr;
	EDIS;
	InitCpuTimers();
	ConfigCpuTimer(&CpuTimer0,150,100000); //100ms
	PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
	PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
	PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
	IER |= 0x0005;
	EINT;
	ERTM;
	CpuTimer0Regs.TCR.bit.TSS = 0;
	while(1)
	{
		while (CpuTimer0.InterruptCount == 0)
		{
		    EALLOW;
		    SysCtrlRegs.WDKEY = 0x55; //service WD #1
		    EDIS;
		}
		CpuTimer0.InterruptCount = 0;
	}
}
void Setup_GPIO(void)
{
	EALLOW;
	GpioCtrlRegs.GPAMUX1.all = 0x0001;
	//GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;
	GpioCtrlRegs.GPAMUX2.all = 0;
	GpioCtrlRegs.GPBMUX1.all = 0;
	GpioCtrlRegs.GPBMUX2.all = 0;
	GpioCtrlRegs.GPCMUX1.all = 0;
	GpioCtrlRegs.GPCMUX2.all = 0;

	GpioCtrlRegs.GPADIR.all = 0;
	GpioCtrlRegs.GPADIR.bit.GPIO0 = 1;
	GpioCtrlRegs.GPBDIR.all = 0;
	GpioCtrlRegs.GPCDIR.all = 0;
	EDIS;
}
void Setup_ePWM1A(void)
{
	EPwm1Regs.TBCTL.bit.CLKDIV = 0; //150MHz/1
	EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1; //150MHz/2
	EPwm1Regs.TBCTL.bit.CTRMODE = 2; //up-down counting mode
	EPwm1Regs.TBCTL.bit.SYNCOSEL = 3; //Disabled sync-out *IMPORTANT
	EPwm1Regs.TBCTL.bit.PRDLD = 0; //Reload tbprd when ctr = 0 *shadow property
	EPwm1Regs.TBCTL.bit.FREE_SOFT = 3; //do not stop durning emulation
	EPwm1Regs.TBPRD = 1875; //tbprds = 150MHz/2(2x2x20kHz) ie 20kHz
	EPwm1Regs.CMPA.half.CMPA = 0; //initial duty cycle
	EPwm1Regs.AQCTLA.all = 0x0060; //set on CTRU = CMPA, clear on CTRD = CMPA
	EPwm1Regs.ETSEL.bit.SOCASEL = 4; //SOC on ctr = 0
	EPwm1Regs.ETSEL.bit.SOCAEN = 1; //SOC enable
	EPwm1Regs.ETSEL.bit.INTEN = 1;		// interrupt enable for ePWM1
	EPwm1Regs.ETSEL.bit.INTSEL = 4;		// interrupt on ctr = 0
	EPwm1Regs.ETPS.all = 0x0101; //SOC and interrupt on first event
}
interrupt void CpuTimer0_isr(void)
{
	CpuTimer0.InterruptCount++;
	EALLOW;
	SysCtrlRegs.WDKEY = 0xAA;  //service WD #2
	EDIS;
	PieCtrlRegs.PIEACK.all = 0x0001;
}

void Setup_adc(void)
{
	//AdcRegs.ADCTRL1.all = 0; //clear all bits int adc control 1 register
	AdcRegs.ADCTRL1.bit.CPS = 0;//ADCCLK = FCLK/(0+1) = FCLK
	AdcRegs.ADCTRL1.bit.ACQ_PS = 7; //Sampling window / Acquisition window is 8*ADCCLK
	AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; //enable cascaded sequencer
	AdcRegs.ADCTRL1.bit.CONT_RUN = 0; //single run mode, ie waits for another trigger at the end of each sequence

	//AdcRegs.ADCTRL2.all = 0; //clear all bits int adc control 2 register
	AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 0; //enable adc start of conversion in sequencer 1 by epwm
	AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; //enable interrupt in sequencer 1
	AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1 = 0; //enable interrupt at End of Sequence (EOS) in sequencer 1
	//initAdc has done all the other needed power-up initialization in ADCTRL3
	AdcRegs.ADCTRL3.bit.ADCCLKPS = 3; //FCLK = HSPCLK/(2*3) = 12.5MHz

	AdcRegs.ADCMAXCONV.all = 0;

	AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 1;
}
interrupt void adc_isr(void)
{
	Voltage_VR1 = AdcMirror.ADCRESULT0;
	AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; //RESET SEQ1 TO RESTART FROM CONV00 IN NEXT SEQUENCE
	AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; //CLEAR ADC INTERRUPT FLAG
	PieCtrlRegs.PIEACK.all = 0x0001;
}
interrupt void ePWM_isr(void)
{
	//static unsigned int Value = 0;
   	EALLOW;
	SysCtrlRegs.WDKEY = 0xAA;		// Service watchdog #3
	EDIS;
   
	EPwm1Regs.CMPA.half.CMPA = Voltage_VR1 * (1875/4095); //convert output to needed counter range
	EPwm1Regs.ETCLR.bit.INT = 1;		// Clear ePWM1 Interrupt flag
    
   	// Acknowledge this interrupt to receive more interrupts from group 3
   	PieCtrlRegs.PIEACK.all = 4;
}

  • sorry............---->>>> QUESTION PART<<<___

    Hello,
    I have been trying to program my eZdsp f28335 to give a variable pulse width based on analogue voltage input but it is not working.
    I am using both epwm1a and adc interrupt. I am using the epwm to trigger a start of conversion in adc. I am using the adc isr to extract digital value which epwm isr sets as CMPA.
    It is however not giving me the expected result. I am only stuck at 100% duty cycle which is the initial condition when CMPA = 0 for the up-down count which I am using. It seems as if the adc isr is hardly called.
    Any ideas/tips will be much appreciated. I have attached the code herewith.... I use ccsv3.3...
    Thanks in advance.
    David.
  • Hi David,

    Have you checked that the ADC ISR is not generated? If you place breakpoints in the ADC ISR, will they be reached when debugging? It is helpful to confirm if it is a problem with the interrupt generation or register configuration.

    Regards,
    Elizabeth
  • Elizabeth Joy said:
    Hi David,

    Have you checked that the ADC ISR is not generated? If you place breakpoints in the ADC ISR, will they be reached when debugging? It is helpful to confirm if it is a problem with the interrupt generation or register configuration.

    Regards,
    Elizabeth

    Yeah. I have done that.... I put the breakpoint at the last line of the ADC isr (PIEACK) and the breakpoint is never activated... I honestly don't know why.... it seems the program is only dancing around the internal while loop...

  • Hi David,

    My other debugging suggestion would be to individually confirm the different peripheral interrupts are generated (EPWM, ADC, CPU Timer) and then combine them in the project. Especially if none of the interrupts are generated now.

    I also recommend debugging EPWM, ADC, CPU Timer example projects in controlSUITE/C2000Ware and compare the register values between those projects and yours.

    Regards,
    Elizabeth