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.

TMS320F2808: Unwanted PWM pulse by adding up a DELAY() inside ADC initialisation code

Part Number: TMS320F2808


Hello,

Each time ADC receives a Start-of-Conversion (SOC) request from ePWMx SOCx trigger to autosequence a series of conversions. I have confused that enabling DELAY() function inside ADC initialisation code, the unwanted PWM pulse was coming. DELAY() function used in ADC  to Power UP the ADC Register bit. So, Why unwanted pulse is coming by adding the DELAY() in ADC initialisation code?

Here i'm adding two snapshot picture:
I: Before adding Delay() in AdcRegs. initialisation
II: After adding Delay() in AdcRegs. initialisation

I: Before adding Delay() in AdcRegs. initialisation

II: After adding Delay() in AdcRegs. initialisation

  • Asim,

    Are you resetting the device between runs?

    It is possible that the ADC and EPWM are configured from a previous execution and they are still active when the Delay() function is running.

    -Tommy
  • Hello Lee,

    I am not using any 'resetting' register bit to reset device from running condition.

    If not use DELAY (), then EPWM is generate proper pulses, and once i used the DELAY (), EPWM is not generate the proper pulse?

  • Anyone else can be help me to rectify this problem, why the unwanted PWM pulses coming after using the DELAY () in ADC peripheral?

  • Asim,

    Sorry, I missed your first reply. Can you try to explicitly reset the device before loading the program?

    What order are you initializing the ADC and EPWM? Can you switch the order to see if it makes a difference?

    -Tommy
  • Hello Lee,

    I have followed your above assumption but not work, still its coming unwanted PWM pulse of after DELAY() function enabled.

  • Asim,

    Can you attach your initialization code with the Use rich formatting -> Attach / Insert File function?

    -Tommy

  • Hello Lee,

    Here inserting the initialisation ADC peripheral code for voltage measurement:

    // Configuring ADC peripheral of voltage measurement
    
    #include "stdio.h"
    #include "stdlib.h"
    #include "DSP280x_Device.h"
    #include "DSP280x_Examples.h"
    
    // Prototype
    void init_system(void);
    void init_adc(void);
    void init_epwm1(void);
    __interrupt void adc_isr(void);
    
    #define ADC_usDELAY  5000L
    
    // Global Variable
    unsigned int Va0;
    
    void main(void)
    {
    	
    	init_system();
    	
    }
    
    void init_system(void)
    {
    //Step1: Initialize System Control Peripheral Clock:
     	EALLOW;
    	SysCtrlRegs.WDKEY = 0x0055;
    	SysCtrlRegs.WDKEY = 0x00AA;
    	SysCtrlRegs.PLLSTS.bit.MCLKSTS = 0;		// Normal condition (Device not in limp mode) 
    	SysCtrlRegs.PLLSTS.bit.CLKINDIV = 0;		// CLKIN divide by 2 is enabled
    	SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;		// Oscillator fail-detect logic is disabled (PLL not issue limp-mode clock)
    	SysCtrlRegs.PLLSTS.bit.PLLLOCKS = 0;		// PLL is lock & CPU is clocked by OSCCLK/2
    	SysCtrlRegs.HISPCP.bit.HSPCLK = 2;		// HSPCLK=SYSCLKOUT/4 (i.e 100/4=25MHz)
    	SysCtrlRegs.LOSPCP.bit.LSPCLK = 0;		// LSPCLK=SYSCLKOUT
    
    	SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;		// Enable clock 
    	SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1;		// Enable clock for ePWM1
    	SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;		// Enable clock for ADC
    	EDIS;
    //Step2: Initialize GPIO Pins:
    	EALLOW;
    	GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0;		// enable pull-up
    	GpioCtrlRegs.GPADIR.bit.GPIO0 = 1;		// output
    	GpioDataRegs.GPASET.bit.GPIO0 = 1;
    	GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;		// ePWM1A, board pin=9
    	EDIS;
    //Step3: Clear all interrupts and initialize PIE vector table:
       	IER = 0x0000;					// Disable CPU interrupts
       	IFR = 0x0000;					// clear all CPU interrupt flags
       	EALLOW;
       	PieVectTable.ADCINT = &adc_isr;			// Initialize PIE Vector Table of ADC
       	EDIS;
    //Step4: Initialize all the Device Peripherals:
       	init_epwm1();
       	init_adc();
    //Step5: Enable interrupts & PIE Control Register:
    
    	PieCtrlRegs.PIEIER1.bit.INTx6 = 1;		// Enable interrupt ADCINT
    
    	IER |= M_INT1; 	// Enable CPU Interrupt 1
    	EINT;		// Enable Global interrupt INTM
    	ERTM;		// Enable Global real time interrupt DBGM
    }
    
    void init_epwm1(void)
    {
    	EPwm1Regs.TBCTL.bit.FREE_SOFT = 3;  	// free run at emul break
    	EPwm1Regs.TBCTL.bit.SYNCOSEL = 1;	// count_zero
    	EPwm1Regs.TBCTL.bit.CLKDIV = 0;		// CLKDIV = 1
    	EPwm1Regs.TBCTL.bit.CTRMODE = 2;	// count up-down mode
    	EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;	// HSPCLKDIV = 1
    	EPwm1Regs.TBCTL.bit.PHSDIR = 0;		// don't care
    	EPwm1Regs.TBCTL.bit.PHSEN = 0;		// disable phase in
    	EPwm1Regs.TBCTL.bit.PRDLD = 0;		// reload on counter = 0
    	EPwm1Regs.TBCTL.bit.SWFSYNC = 0;	// no sw force sync out
    	EPwm1Regs.TBPRD = 128;			// 390.625kHz, 2.56us
    	EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    	EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    	EPwm1Regs.CMPA.half.CMPA = 64;
    	EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
    	EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
    
    	EPwm1Regs.ETSEL.bit.SOCASEL = 1;	// SOCA at ZERO event
    	EPwm1Regs.ETSEL.bit.SOCAEN = 1;		// enable SOCA
    	EPwm1Regs.ETPS.bit.SOCAPRD = 1;		// generate SOCA on 1st event
    
    }
    
    void init_adc(void)
    {
    	// ADC Configuration
    	AdcRegs.ADCREFSEL.bit.REF_SEL = 0;		// Internal reference selected
    	AdcRegs.ADCTRL3.bit.ADCBGRFDN = 1;		// Power Up the Band gap & Reference Circuitry
    	AdcRegs.ADCTRL3.bit.ADCPWDN = 1;        	// Power Up the ADC Analog Circuitry
    	AdcRegs.ADCTRL3.bit.ADCCLKPS = 2;	 	// HSPCLK=25MHz; ADC clock: FCLK=HSPCLK / 2 * ADCCLKPS
    	AdcRegs.ADCTRL3.bit.SMODE_SEL = 0;		// SEQUENTIAL sampling mode
    	DELAY_US(ADC_usDELAY);				// ADC_usDELAY = 5000L
    
    	AdcRegs.ADCTRL1.bit.CPS = 0;			// 6.25MHz; ADCCLK=FCLK/1;
    	AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; 		// CASCADED Sequencer
    	AdcRegs.ADCTRL1.bit.ACQ_PS = 15; 		// 2.56us, S/H =(ACQ_PS+1) x tADCCLK;
    	AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0;   	// 1 Conversion
    	AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0; 		// ADCINA0 as input
    	AdcRegs.ADCTRL1.bit.CONT_RUN = 1;		// Continuous run mode
    
    	AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;		// ePWM1 SOCA trigger for SEQ1
    	AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;		// enable SEQ1 interrupt
    	
    }
    
    __interrupt void adc_isr(void)
    {
    
    	Va0 = AdcMirror.ADCRESULT0;			// store results globally
    
    	
     	AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;		// Clear INT SEQ1 bit
     	PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; 	// Acknowledge group 1 
     	
    }
    

  • Asim,

    Can you try the attached to see if it helps?  I tried to put everything into an idle state during initialization and only started the EPWM counter at the end.

    // Configuring ADC peripheral of voltage measurement
    
    #include "stdio.h"
    #include "stdlib.h"
    #include "DSP280x_Device.h"
    #include "DSP280x_Examples.h"
    
    // Prototype
    void init_system(void);
    void init_adc(void);
    void init_epwm1(void);
    __interrupt void adc_isr(void);
    
    #define ADC_usDELAY  5000L
    
    // Global Variable
    unsigned int Va0;
    
    void main(void)
    {
    	
    	init_system();
    	
    }
    
    void init_system(void)
    {
    //Step1: Initialize System Control Peripheral Clock:
     	EALLOW;
    	SysCtrlRegs.WDKEY = 0x0055;
    	SysCtrlRegs.WDKEY = 0x00AA;
    	SysCtrlRegs.PLLSTS.bit.MCLKSTS = 0;		// Normal condition (Device not in limp mode) 
    	SysCtrlRegs.PLLSTS.bit.CLKINDIV = 0;		// CLKIN divide by 2 is enabled
    	SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;		// Oscillator fail-detect logic is disabled (PLL not issue limp-mode clock)
    	SysCtrlRegs.PLLSTS.bit.PLLLOCKS = 0;		// PLL is lock & CPU is clocked by OSCCLK/2
    	SysCtrlRegs.HISPCP.bit.HSPCLK = 2;		// HSPCLK=SYSCLKOUT/4 (i.e 100/4=25MHz)
    	SysCtrlRegs.LOSPCP.bit.LSPCLK = 0;		// LSPCLK=SYSCLKOUT
    
    	SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;		// Enable clock 
    	SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1;		// Enable clock for ePWM1
    	SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;		// Enable clock for ADC
    	EDIS;
    //Step2: Initialize GPIO Pins:
    	EALLOW;
    	GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0;		// enable pull-up
    	GpioCtrlRegs.GPADIR.bit.GPIO0 = 1;		// output
    	GpioDataRegs.GPASET.bit.GPIO0 = 1;
    	GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;		// ePWM1A, board pin=9
    	EDIS;
    //Step3: Clear all interrupts and initialize PIE vector table:
    	EPwm1Regs.TBCTL.bit.CTRMODE = 3;  // Freeze EPWM
    	AdcRegs.ADCTRL1.bit.RESET = 1;    // Reset ADC
    
       	IER = 0x0000;					// Disable CPU interrupts
       	IFR = 0x0000;					// clear all CPU interrupt flags
       	EALLOW;
       	PieVectTable.ADCINT = &adc_isr;			// Initialize PIE Vector Table of ADC
       	EDIS;
    //Step4: Initialize all the Device Peripherals:
    
       	init_adc();
    	init_epwm1();
    //Step5: Enable interrupts & PIE Control Register:
    
    	IER |= M_INT1; 	// Enable CPU Interrupt 1
    	EINT;		// Enable Global interrupt INTM
    	ERTM;		// Enable Global real time interrupt DBGM
    
        PieCtrlRegs.PIEIER1.bit.INTx6 = 1;		// Enable interrupt ADCINT
    	EPwm1Regs.TBCTL.bit.CTRMODE = 2;	// count up-down mode
    }
    
    void init_epwm1(void)
    {
    	EPwm1Regs.TBCTL.bit.FREE_SOFT = 3;  	// free run at emul break
    	EPwm1Regs.TBCTL.bit.SYNCOSEL = 1;	// count_zero
    	EPwm1Regs.TBCTL.bit.CLKDIV = 0;		// CLKDIV = 1
    //	EPwm1Regs.TBCTL.bit.CTRMODE = 2;	// count up-down mode
    	EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;	// HSPCLKDIV = 1
    	EPwm1Regs.TBCTL.bit.PHSDIR = 0;		// don't care
    	EPwm1Regs.TBCTL.bit.PHSEN = 0;		// disable phase in
    	EPwm1Regs.TBCTL.bit.PRDLD = 0;		// reload on counter = 0
    	EPwm1Regs.TBCTL.bit.SWFSYNC = 0;	// no sw force sync out
    	EPwm1Regs.TBPRD = 128;			// 390.625kHz, 2.56us
    	EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    	EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    	EPwm1Regs.CMPA.half.CMPA = 64;
    	EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
    	EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
    
    	EPwm1Regs.ETSEL.bit.SOCASEL = 1;	// SOCA at ZERO event
    	EPwm1Regs.ETSEL.bit.SOCAEN = 1;		// enable SOCA
    	EPwm1Regs.ETPS.bit.SOCAPRD = 1;		// generate SOCA on 1st event
    
    }
    
    void init_adc(void)
    {
    	// ADC Configuration
    	AdcRegs.ADCREFSEL.bit.REF_SEL = 0;		// Internal reference selected
    	AdcRegs.ADCTRL3.bit.ADCBGRFDN = 1;		// Power Up the Band gap & Reference Circuitry
    	AdcRegs.ADCTRL3.bit.ADCPWDN = 1;        	// Power Up the ADC Analog Circuitry
    	AdcRegs.ADCTRL3.bit.ADCCLKPS = 2;	 	// HSPCLK=25MHz; ADC clock: FCLK=HSPCLK / 2 * ADCCLKPS
    	AdcRegs.ADCTRL3.bit.SMODE_SEL = 0;		// SEQUENTIAL sampling mode
    
    	AdcRegs.ADCTRL1.bit.CPS = 0;			// 6.25MHz; ADCCLK=FCLK/1;
    	AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; 		// CASCADED Sequencer
    	AdcRegs.ADCTRL1.bit.ACQ_PS = 15; 		// 2.56us, S/H =(ACQ_PS+1) x tADCCLK;
    	AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0;   	// 1 Conversion
    	AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0; 		// ADCINA0 as input
    	AdcRegs.ADCTRL1.bit.CONT_RUN = 1;		// Continuous run mode
    
        DELAY_US(ADC_usDELAY);				// ADC_usDELAY = 5000L
    
    	AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;		// ePWM1 SOCA trigger for SEQ1
    	AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;		// enable SEQ1 interrupt
    	
    }
    
    __interrupt void adc_isr(void)
    {
    
    	Va0 = AdcMirror.ADCRESULT0;			// store results globally
    
    	
     	AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;		// Clear INT SEQ1 bit
     	PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; 	// Acknowledge group 1 
     	
    }
    

    -Tommy

  • Lee,
    Same things happening, their is no change. The unwanted PWM pulses coming at GPIO ePWM1A pin.

    My objective of this code is "To perform multiple conversion in ADC sequence by getting proper ePWM counter pulse". If ePWM counter pulse not proper then it can impossible to perform multiple conversions automatically at ADC.
  • Asim,

    I noticed that there are a handful of differences in your init_system() configuration vs the TI example code initialization. If I revert the system configuration to the TI example code, things seem to work fine on my setup.

    I think your DELAY_US() issue might be due to the watchdog. I see that the TI example code will disable the watchdog whereas your initialization merely services it once. I would not be surprised if the watchdog might be throwing a reset during the delay.

    -Tommy
  • Lee,
    No changes, after disable the watchdog timer.
  • Asim,

    Are you using a TI board or a custom design?  Can you start with the adc_soc example first to make sure that it works?

    I did not see any strange behavior on my setup.

    -Tommy