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.

TMS320F28388D: Strong oscillation/noise on ADCINB3 (and ADCIND3)

Part Number: TMS320F28388D
Other Parts Discussed in Thread: TINA-TI

Hello. We are sampling four channels simultaneously using ePWM2 via DMA and using the channel 3 of every one of four ADCs (ie ADCINC3, ADCINA3, ADCINB3 & ADCIND3).

adcRegs->ADCSOC0CTL.bit.TRIGSEL = 7;

The data is sampled synchrosnously, however we see a strong (oscillation or coupling?) signal when using ADCINB3 and ADCIND3 (not with ADCINC3 and ADCINA3). The circuit is the same for all 4 channels and we even tried to shortcircuit from the source to the shortest path of our PCB board with the same result.

We even tried to interchange every signal source from ADCINC3 to ADCINB3 and viceversa, with the same result....everything connected to ADCINB3 and ADCIND3 is noisy and not with ADCINC3 and ADCINA3.

To give you and idea here is a video and the effect we are seeing. All signals should be constant, hoever ADCINB3 (yellow) and ADCIND3 (blue) are oscillating:

And this is our circuit regarding ADCs:

This is a problem for us since we are using the phase of the signal.

This happens in all the boards.

What is your suggestion for this issue? Is it crosstalk? Is there any issue with the synch of ePWM accross all ADCs?

Is there any register we should modify?

Thank you

  • Hello,

    I don't understand the circuits on the right side of your diagram above - why are ADC inputs A0 and B1 connected to an op amp input?

    Also please clarify, what signal exactly is being measured/showing the oscillation in the video above? Is it the input to ADCINB3/ADCIND3, the VREFHI pin, or something else?

    In terms of synchronous sampling, the following points are important:

    • The ACQPS must be the same for the SOCs being used across all the ADCs being sampled. Also to maintain the same timing, the ADC prescale value (ADCCTL2.PRESCALE) must be identical for all the ADCs. It is recommended to use whole numbers for PRESCALE and not fractional dividers.
    • If multiple triggers are used, then care must be taken to ensure the triggers arrive simultaneously. Ideally, you want to use the same trigger for all 4 SOCs to ensure synchronous sampling.
    • Review your ADC input network to ensure stability in combination with the ADC input pin being sampled. I would recommend using TINA-TI or PSpice to simulate your input network, using one of the simulation models provided in our application report: ADC Input Circuit Evaluation for C2000 MCUs.

    Best regards,
    Ibukun

  • Hello.

    The DAC OUTPUTS A0 and B1 are connected to an op amp input,  yes.

    The signals measured in the video are ADCINB3, ADCINC3, ADCINA3 and ADCIND3. B3 is yellow and D3 is blue.

    ACQPS are the same for all the SOCs of all ADCs. Prescale is 6 for all ADCs.

    The only trigger is ePWM2 for all SOCs (only one sequence on one pin per ADC)

    The input network is the SAME for all ADCs and is well design, and only on two we have that behaviour.

    Best regards

  • Got it. If possible, can I review the input network for the ADCIN pins?

    Sometimes, it may be necessary to add a small snubbing resistor if you have a large capacitor on the ADC input pin to help address stability issues. This is why I recommended simulating the input network using our tools and input models (provided in the app report) to verify stability.

    Best regards,
    Ibukun

  • Thank you.

    Is it possible to send it to you privately?

    Thank you

  • I just sent you a friend request. Once you've accepted you should be able to send it to me privately.

  • We tried changing S/H timing via ACQPS and also lowering the input impedance and increasing capacitance.

    Is it possible that some noise, present in any other pin of the ADC (not used) is able to be measured in our pins?

    Do you recommned grounding the not used ADC pins?

  • We tried changing S/H timing via ACQPS and also lowering the input impedance and increasing capacitance.

    Is it possible that some noise, present in any other pin of the ADC (not used) is able to be measured in our pins?

    Do you recommned grounding the not used ADC pins?

  • Hello,

    It's always a good idea to ground unused pins that are unused. All the pins for each ADC are connected to an input selection mux (CHSEL), as the ADC can only convert one channel at a time. We have done extensive testing on channel-to-channel crosstalk/coupling. Some noise coupling is possible at high frequencies (MHz range), but certainly nothing like the magnitude you're showing here though. As I said previously, ADC input pin impedance is very high, so this most likely reflects an unseen issue outside the MCU.

    One more question I have for you: if you are operating the ADCs at the same time, are you ensuring that the conversions are synchronous? If ADCs are operated asynchronously (that is, conversions don't start and end at the same time but are overlapping), there can be coupling from ADC to ADC. To avoid this, if simultaneous operation is required then ensure that both ADCs are configured to the same ACQPS and ADCCLK divider (prescale). This would be reflected in the conversions though - in other words, the symptom here would be reduced linearity/AC performance in the converted output. I don't really see a scenario in which a signal could pass through from ADC to ADC and onto a different pin, and I've spent some time to review our characterization data for this device to confirm this.

  • Thank you Ibukun.

    We are using the same epwm to trigger the four ADCs on the same SOC (only one Soc per ADc), so the are synchronous.

    Here you will find our init functions, just in case you are able to review.

    //
    // ConfigureADC - Write ADC configurations and power up the ADC for both
    //                ADC A and ADC B
    //
    
    void ConfigureADC_all4(void)
    {
    
    	EALLOW;
    
    //
    // Write prescale configurations
    //
    
    	AdcaRegs.ADCCTL2.bit.PRESCALE = 6;        // 6; // Set ADCCLK divider to /4
    	AdcbRegs.ADCCTL2.bit.PRESCALE = 6;        //6;
    	AdccRegs.ADCCTL2.bit.PRESCALE = 6;        //6;
    	AdcdRegs.ADCCTL2.bit.PRESCALE = 6;        //6;
    	/**/
    //
    // Set mode
    //
    	if (ADC_12_o_16_bits)
    	{
    		AdcSetMode(ADC_ADCA, ADC_RESOLUTION_16BIT, ADC_SIGNALMODE_SINGLE);
    		AdcSetMode(ADC_ADCB, ADC_RESOLUTION_16BIT, ADC_SIGNALMODE_SINGLE);
    		AdcSetMode(ADC_ADCC, ADC_RESOLUTION_16BIT, ADC_SIGNALMODE_SINGLE);
    		AdcSetMode(ADC_ADCD, ADC_RESOLUTION_16BIT, ADC_SIGNALMODE_SINGLE);
    	}
    	else
    	{
    
    		AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
    		AdcSetMode(ADC_ADCB, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
    		AdcSetMode(ADC_ADCC, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
    		AdcSetMode(ADC_ADCD, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
    
    	}
    //
    // Set pulse positions to late
    //
    	AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;
    	AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;
    	AdccRegs.ADCCTL1.bit.INTPULSEPOS = 1;
    	AdcdRegs.ADCCTL1.bit.INTPULSEPOS = 1;
    
    //
    // Power up the ADC
    //
    	AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
    	AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;
    	AdccRegs.ADCCTL1.bit.ADCPWDNZ = 1;
    	AdcdRegs.ADCCTL1.bit.ADCPWDNZ = 1;
    
    	//ADC_setVREF(ADCA_BASE, ADC_REFERENCE_INTERNAL, ADC_REFERENCE_3_3V); // VREF internal 3.3V
    
    //
    // Delay for 1ms to allow ADCs time to power up
    //
    	DELAY_US(1000);
    
    	EDIS;
    
    }
    
    //
    // ConfigureEPWM - Set up the ePWM2 module so that the A output has a period
    //                 of 40us with a 50% duty. The SOCA signal is coincident with
    //                 the rising edge of this.
    //
    void ConfigureEPWM(void)
    {
    
    	
    //
    // Make the timer count up with a period of 100us -  1SYSCLK = 100MHz
    //
    	EPwm2Regs.TBCTL.all = 0x0000;
    	EPwm2Regs.TZCTL.all = 0x0000;
    
    	EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
    
    	EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;
    	//  EPwm2Regs.TBCTL.bit. SYNCOSEL = TB_CTR_ZERO;
    
    
    
    	EPwm2Regs.TBPRD = 399;            //250khz 
    
    
    
    //
    //
    // Set the A output on zero and reset on CMPA
    //
    	EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;
    	EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;
    
    //pak
    
    	EPwm2Regs.AQCTLA.bit.PRD = AQ_TOGGLE;        // Toggle on PRD
    
    //
    // Set CMPA to 20us to get a 50% duty
    //
    	EPwm2Regs.CMPA.bit.CMPA = 100;        //80;//1200;//2000
    
    //
    // Start ADC when timer equals zero (note: don't enable yet)
    //
    	EPwm2Regs.ETSEL.bit.SOCASEL = ET_CTR_ZERO;
    	EPwm2Regs.ETPS.bit.SOCAPRD = ET_1ST;
    
    //
    // Enable initialization of the SOCA event counter. Since we are
    // disabling the ETSEL.SOCAEN bit, we need a way to reset the SOCACNT.
    // Hence, enable the counter initialize control.
    //
    	EPwm2Regs.ETCNTINITCTL.bit.SOCAINITEN = 1;
    }
    
    void SetupADCContinuous(volatile struct ADC_REGS *adcRegs, Uint16 channel)
    {
    	Uint16 acqps;
    
    //
    // Determine minimum acquisition window (in SYSCLKS) based on resolution
    //
    	if (ADC_RESOLUTION_12BIT == adcRegs->ADCCTL2.bit.RESOLUTION)
    	{
    		acqps = 14; //14+1  - 75ns
    	}
    	else //resolution is 16-bit
    	{
    		acqps = 63; //800; - 250kHz //400 -500kHz;//63;//borrame_monop 63; //63+1 - 320ns
    	}
    
    //
    //Select the channels to convert and end of conversion flag
    //
    
    	EALLOW;
    
    	//
    	// SOCs will convert on same specified channel
    	//
    	adcRegs->ADCSOC0CTL.bit.CHSEL = channel;
    	adcRegs->ADCSOC1CTL.bit.CHSEL = channel;
    	adcRegs->ADCSOC2CTL.bit.CHSEL = channel;
    	adcRegs->ADCSOC3CTL.bit.CHSEL = channel;
    	adcRegs->ADCSOC4CTL.bit.CHSEL = channel;
    	adcRegs->ADCSOC5CTL.bit.CHSEL = channel;
    	adcRegs->ADCSOC6CTL.bit.CHSEL = channel;
    	adcRegs->ADCSOC7CTL.bit.CHSEL = channel;
    	adcRegs->ADCSOC8CTL.bit.CHSEL = channel;
    	adcRegs->ADCSOC9CTL.bit.CHSEL = channel;
    	adcRegs->ADCSOC10CTL.bit.CHSEL = channel;
    	adcRegs->ADCSOC11CTL.bit.CHSEL = channel;
    	adcRegs->ADCSOC12CTL.bit.CHSEL = channel;
    	adcRegs->ADCSOC13CTL.bit.CHSEL = channel;
    	adcRegs->ADCSOC14CTL.bit.CHSEL = channel;
    	adcRegs->ADCSOC15CTL.bit.CHSEL = channel;
    
    	//
    	// Sample window is acqps + 1 SYSCLK cycles
    	//
    	adcRegs->ADCSOC0CTL.bit.ACQPS = acqps;
    	adcRegs->ADCSOC1CTL.bit.ACQPS = acqps;
    	adcRegs->ADCSOC2CTL.bit.ACQPS = acqps;
    	adcRegs->ADCSOC3CTL.bit.ACQPS = acqps;
    	adcRegs->ADCSOC4CTL.bit.ACQPS = acqps;
    	adcRegs->ADCSOC5CTL.bit.ACQPS = acqps;
    	adcRegs->ADCSOC6CTL.bit.ACQPS = acqps;
    	adcRegs->ADCSOC7CTL.bit.ACQPS = acqps;
    	adcRegs->ADCSOC9CTL.bit.ACQPS = acqps;
    	adcRegs->ADCSOC10CTL.bit.ACQPS = acqps;
    	adcRegs->ADCSOC11CTL.bit.ACQPS = acqps;
    	adcRegs->ADCSOC12CTL.bit.ACQPS = acqps;
    	adcRegs->ADCSOC13CTL.bit.ACQPS = acqps;
    	adcRegs->ADCSOC14CTL.bit.ACQPS = acqps;
    	adcRegs->ADCSOC15CTL.bit.ACQPS = acqps;
    
    	//
    	// Trigger SCO0 from EPWM2SOCA
    	//
    	adcRegs->ADCSOC0CTL.bit.TRIGSEL = 7;
    
    	//
    	// Trigger all other SOCs from INT1 (EOC on SOC0)
    	//
    	adcRegs->ADCINTSOCSEL1.bit.SOC1 = 1;
    	adcRegs->ADCINTSOCSEL1.bit.SOC2 = 0;
    	adcRegs->ADCINTSOCSEL1.bit.SOC3 = 0;           //1;
    	adcRegs->ADCINTSOCSEL1.bit.SOC4 = 0;           // 1;
    	adcRegs->ADCINTSOCSEL1.bit.SOC5 = 0;           // 1;
    	adcRegs->ADCINTSOCSEL1.bit.SOC6 = 0;           // 1;
    	adcRegs->ADCINTSOCSEL1.bit.SOC7 = 0;           // 1;
    	adcRegs->ADCINTSOCSEL2.bit.SOC8 = 0;           // 1;
    	adcRegs->ADCINTSOCSEL2.bit.SOC9 = 0;           // 1;
    	adcRegs->ADCINTSOCSEL2.bit.SOC10 = 0;           // 1;
    	adcRegs->ADCINTSOCSEL2.bit.SOC11 = 0;           // 1;
    	adcRegs->ADCINTSOCSEL2.bit.SOC12 = 0;           // 1;
    	adcRegs->ADCINTSOCSEL2.bit.SOC13 = 0;           // 1;
    	adcRegs->ADCINTSOCSEL2.bit.SOC14 = 0;           // 1;
    	adcRegs->ADCINTSOCSEL2.bit.SOC15 = 0;           // 1;
    
    	adcRegs->ADCINTSEL1N2.bit.INT1E = 1;           // Enable INT1 flag
    	adcRegs->ADCINTSEL1N2.bit.INT2E = 0;        //1;// 1;    // Enable INT2 flag
    	adcRegs->ADCINTSEL3N4.bit.INT3E = 0;           // Disable INT3 flag
    	adcRegs->ADCINTSEL3N4.bit.INT4E = 0;           // Disable INT4 flag
    
    	adcRegs->ADCINTSEL1N2.bit.INT1CONT = 1;
    	adcRegs->ADCINTSEL1N2.bit.INT2CONT = 0;           //1;// 1;
    
    	adcRegs->ADCINTSEL1N2.bit.INT1SEL = 0;           // End of SOC0
    	adcRegs->ADCINTSEL1N2.bit.INT2SEL = 0;           //1;// 15; // End of SOC15
    
    	EDIS;
    	/**/
    
    }
    
    
    void DMAInit_all4(void)
    {
    
    	//
    	// Initialize DMA
    	//
    	DMAInitialize();
    
    	/////////////////////////////////////////////////////////////////////////
    	//
    	// DMA set up for first ADC
    	//
    
    
    	DMACH1AddrConfig(adcData_compuesto, &AdccResultRegs.ADCRESULT0);//canal 1
    
    
    	DmaRegs.CH1.BURST_SIZE.bit.BURSTSIZE = 0;
    
    	DMACH1TransferConfig(MUESTRAS_REALES_DMA + GUARDA_MUESTRAS - 1, 0, 2);
    
    	
    	DMACH1ModeConfig(
    	DMA_ADCCINT1,
    						PERINT_ENABLE,
    						ONESHOT_DISABLE,
    						CONT_ENABLE,
    						SYNC_DISABLE,
    						SYNC_SRC,
    						OVRFLOW_DISABLE,
    						SIXTEEN_BIT,
    						CHINT_END,
    						CHINT_ENABLE);
    
    	//
    	// DMA set up for second ADC
    	//
    	
    	DMACH2AddrConfig(&adcData_compuesto[1], &AdcaResultRegs.ADCRESULT0); //canal 2
    
    
    
    	DmaRegs.CH2.BURST_SIZE.bit.BURSTSIZE = 0;
    
    	
    	DMACH2TransferConfig(MUESTRAS_REALES_DMA + GUARDA_MUESTRAS - 1, 0, 2);
    
    	DMACH2ModeConfig(
    	//DMA_ADCAINT2,
    			DMA_ADCAINT1,
    			PERINT_ENABLE,
    			ONESHOT_DISABLE,
    			CONT_ENABLE,
    			SYNC_DISABLE,
    			SYNC_SRC,
    			OVRFLOW_DISABLE,
    			SIXTEEN_BIT,
    			CHINT_END,
    			CHINT_DISABLE);
    
    	/////////////////////////////////////////////////////////////////////////////////////
    	////////////////////////////////////////////////////////////////////////////////////////////
    
    	/////////////////////////////////////////////////////////////////////////
    	//
    	// DMA set up for third ADC
    	//
    
    
    	 DMACH3AddrConfig(adcData_compuesto_MONOP, &AdcbResultRegs.ADCRESULT0);//canal 3
    	
    
    	DmaRegs.CH3.BURST_SIZE.bit.BURSTSIZE = 0;
    
    	DMACH3TransferConfig(MUESTRAS_REALES_DMA + GUARDA_MUESTRAS - 1, 0, 2);//copia CW - corrige int
    
    	
    	DMACH3ModeConfig(
    	DMA_ADCBINT1,
    						PERINT_ENABLE,
    						ONESHOT_DISABLE,
    						CONT_ENABLE,
    						SYNC_DISABLE,
    						SYNC_SRC,
    						OVRFLOW_DISABLE,
    						SIXTEEN_BIT,
    						CHINT_END,
    						CHINT_ENABLE);
    
    	//
    	// DMA set up for second ADC
    	//
    	
    	 DMACH4AddrConfig(&adcData_compuesto_MONOP[1], &AdcdResultRegs.ADCRESULT0); //canal 4
    	 
    	DmaRegs.CH4.BURST_SIZE.bit.BURSTSIZE = 0;
    
    	//
    	DMACH4TransferConfig(MUESTRAS_REALES_DMA + GUARDA_MUESTRAS - 1, 0, 2);
    
    	DMACH4ModeConfig(
    	//DMA_ADCAINT1,
    			DMA_ADCDINT1,
    			PERINT_ENABLE,
    			ONESHOT_DISABLE,
    			CONT_ENABLE,
    			SYNC_DISABLE,
    			SYNC_SRC,
    			OVRFLOW_DISABLE,
    			SIXTEEN_BIT,
    			CHINT_END,
    			CHINT_DISABLE);
    }

    Are you able to test this setup on your board for checking if you see this behaviour?

    On the other hand, I shared with you via private message some results of testing.

  • Hello Ibukun.

    Were you able to check this setup?

    Best Regards

  • Hello PAk,

    I have been discussing this issue further with our team here and working on debugging on our setup as well. Will revert as soon as I can.

    Thanks,
    Ibukun

  • Thank you!!

    Do you see the same issue in your setup with 4 channels activated and DMA?

  • Hello PAk, apologies for the delay. I'm still working on this and will revert later today.

  • Hello Ibukun.

    Do you have any feedback?

    Thanks

  • Hello Ibukun.

    Have you been able to test on your side?

    Best Regards

  • Hi there, apologies for the delayed response, as I have been out of office in the past week. I am still working on investigating this issue with my colleagues. So far we have been unable to reproduce this behavior on our end, but we are still working on helping you find an answer. As I've mentioned previously, the ADC input pins have a very high input impedance so it does not make sense that one would couple onto another. One thing I'm not sure I've clarified from previous inquiries: does the oscillation only happen when the ADCs are actively converting, or does it happen continuously once the pins are connected?

  • Thank you Ibukun.

    Have  you used the source code we provided?

    Regarding your question, what do you mean by actively converting or pins are connected?

  • What I mean is: does the oscillation happen if the ADC is not converting -- in other words, if you disable the SOC triggers so the ADCs are idle, do you still see the issue? Or does it only happen when the ADCs are being triggered and sampling the signal?

    Best regards,
    Ibukun

  • To check the oscillation (the video) we are using our own application, after ADC convertion.

    Do you want us to disable the Socs and test with a scope?

  • Yes, please do.

    There is no internal signal path between ADCB and ADCD input muxes, and this device does not have an analog interconnect that could potentially link the two ADC input pins with each other. All of these pins have an input impedance in the 3-10MOhm range so leakage could not be an issue, and these pins are not in close proximity with each other so the possibility of inductive coupling is not there. From a chip design point of view there is nothing we can point to that could explain what you are seeing.

    Perhaps you have some other signal source on your board that is in close proximity with these pins that is causing coupling?

    Thanks,
    Ibukun

  • Will try to disable all ADCs, but I see the same signals on the scope.

    Is it recommended to stop also the PWM timers?

  • Yes, to narrow it down. Let's see if the oscillations happen when the PWMs are not running.

    The oscillation persisting when the ADC SOCs are disabled confirms that the ADC's are not responsible for the signal coupling.

    Best regards,
    Ibukun