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: Running multiple ADC of same module simultaneously

Part Number: TMS320F28379D

Tool/software: Code Composer Studio

I am trying to read three ADC - ADCA0, ADCA1, ADCA3 triggered from EPWM2SOCA. I have made edits in the Lab6 solution code of F28379D one day workshop. But it is not happening. The code is running for single Adc but not for multiple Adcs. The code of Adc.c is only attached. Rest of the code is as given from beginning.

Thanks in advance.

/**********************************************************************
* File: Adc.c -- Solution File
* Devices: TMS320F28x7x
* Author: C2000 Technical Training, Texas Instruments
**********************************************************************/

#include "Lab.h"				// Main include file


/**********************************************************************
* Function: InitAdca()
*
* Description: Initializes ADC-A on the F28x7x
**********************************************************************/
void InitAdca(void)
{
	asm(" EALLOW");						// Enable EALLOW protected register access

//--- Reset the ADC.  This is good programming practice.
	DevCfgRegs.SOFTPRES13.bit.ADC_A = 1;	// ADC is reset
	DevCfgRegs.SOFTPRES13.bit.ADC_A = 0;	// ADC is released from reset


//--- Configure the ADC base registers
	AdcaRegs.ADCCTL1.all = 0x0004;		// Main ADC configuration
// bit 15-14     00:     reserved
// bit 13        0:      ADCBSY, ADC busy, read-only
// bit 12        0:      reserved
// bit 11-8      0's:    ADCBSYCHN, ADC busy channel, read-only
// bit 7         0:      ADCPWDNZ, ADC power down, 0=powered down, 1=powered up
// bit 6-3       0000:   reserved
// bit 2         1:      INTPULSEPOS, INT pulse generation, 0=start of conversion, 1=end of conversion
// bit 1-0       00:     reserved

	AdcaRegs.ADCCTL2.all = 0x0006;		// ADC clock configuration

// bit 15-8      0's:    reserved
// bit 7         0:      SIGNALMODE, configured by AdcSetMode() below to get calibration correct
// bit 6         0:      RESOLUTION, configured by AdcSetMode() below to get calibration correct
// bit 5-4       00:     reserved
// bit 3-0       0110:   PRESCALE, ADC clock prescaler.  0110=CPUCLK/4

	AdcaRegs.ADCBURSTCTL.all = 0x0000;

// bit 15        0:      BURSTEN, 0=burst mode disabled, 1=burst mode enabled
// bit 14-12     000:    reserved
// bit 11-8      0000:   BURSTSIZE, 0=1 SOC converted (don't care)
// bit 7-6       00:     reserved
// bit 5-0       000000: BURSTTRIGSEL, 00=software only (don't care)

//--- Call AdcSetMode() to configure the resolution and signal mode.
//    This also performs the correct ADC calibration for the configured mode.
    AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);

//--- SOC0 configuration
	AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 7;		// Trigger using ePWM2-ADCSOCA
	AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0;			// Convert channel ADCINA0 (Ch. 0)
	AdcaRegs.ADCSOC0CTL.bit.ACQPS = 10;			// Acquisition window set to (19+1)=20 cycles (100 ns with 200 MHz SYSCLK)

	AdcaRegs.ADCINTSOCSEL1.bit.SOC0 = 0;		// No ADC interrupt triggers SOC0 (TRIGSEL field determines trigger)

	AdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 7;        // Trigger using ePWM2-ADCSOCA
    AdcaRegs.ADCSOC1CTL.bit.CHSEL = 1;          // Convert channel ADCINA0 (Ch. 0)
    AdcaRegs.ADCSOC1CTL.bit.ACQPS = 10;         // Acquisition window set to (19+1)=20 cycles (100 ns with 200 MHz SYSCLK)

    AdcaRegs.ADCINTSOCSEL1.bit.SOC1 = 0;        // No ADC interrupt triggers SOC0 (TRIGSEL field determines trigger)

    AdcaRegs.ADCSOC2CTL.bit.TRIGSEL = 7;        // Trigger using ePWM2-ADCSOCA
    AdcaRegs.ADCSOC2CTL.bit.CHSEL = 3;          // Convert channel ADCINA0 (Ch. 0)
    AdcaRegs.ADCSOC2CTL.bit.ACQPS = 10;         // Acquisition window set to (19+1)=20 cycles (100 ns with 200 MHz SYSCLK)

    AdcaRegs.ADCINTSOCSEL1.bit.SOC2 = 0;        // No ADC interrupt triggers SOC0 (TRIGSEL field determines trigger)

	AdcaRegs.ADCSOCPRICTL.bit.SOCPRIORITY = 0;	// All SOCs handled in round-robin mode




//--- ADCA1 interrupt configuration
	AdcaRegs.ADCINTSEL1N2.bit.INT1CONT = 1;		// Interrupt pulses regardless of flag state
	AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;		// Enable the interrupt in the ADC
	AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0x2;		// EOC0 triggers the interrupt

//--- Enable the ADC interrupt
	PieCtrlRegs.PIEIER1.bit.INTx1 = 1;			// Enable ADCA1 interrupt in PIE group 1
	IER |= 0x0FFF;								// Enable INT1 in IER to enable PIE group

//--- Finish up
	AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;			// Power up the ADC
	DelayUs(1000);								// Wait 1 ms after power-up before using the ADC
	asm(" EDIS");								// Disable EALLOW protected register access

} // end InitAdc()


//--- end of file -----------------------------------------------------

  • Assuming you're running at 200MHz, your sampling window is a little too short I think. Please see your datasheet for the minimum time expected.

    Can you give me more details about in what way it isn't working? Is the ADC interrupt being triggered or no? Are the ADC results correct for 1 of the channels but incorrect for the other 2?

    Whitney

  • Dear Whitney,

    The problem over here is that the code is not going into the interrupt. I want the code to reach interrupt once all the three SOCs, SOC0, SOC1 and SOC2 completes reading the result and then EOC2 triggers ADCINT1. But somehow my ISR is not running. I have verified this because the led is not blinking as the code in interrupt.

    interrupt void ADCA1_ISR(void)						// PIE1.1 @ 0x000D40  ADC-A interrupt #1
    {
    static Uint16 *AdcBufPtr = AdcBuf;                  // Pointer to buffer
    static Uint16 *AdcBufPtrr = AdcBuff;
    static Uint16 iQuadratureTable = 0;                 // Quadrature table index
    static volatile Uint16 GPIO34_count = 0;            // Counter for pin toggle
    static volatile Uint16 PwmModDelay = 0;             // Counter to change PWM
    static volatile Uint16 PwmModDir = 1;               // Create a direction for PWM
    static volatile Uint16 PwmCmpaVal = PWM_MAX_DUTY;   // Starting value for PWM
    
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;         // Must acknowledge the PIE group
    
    //--- Manage the ADC registers
        AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;          // Clear ADCINT1 flag
    
    //--- Read the ADC result
        *AdcBufPtr++ =  AdcaResultRegs.ADCRESULT0;          // Read the result
        *AdcBufPtrr++ = AdcbResultRegs.ADCRESULT0;
    //--- Brute-force the circular buffer
        if( AdcBufPtr == (AdcBuf + ADC_BUF_LEN) )
        {
            AdcBufPtr = AdcBuf;                     // Rewind the pointer to beginning
        }
    
        if( AdcBufPtrr == (AdcBuff + ADC_BUF_LEN) )
            {
              AdcBufPtrr = AdcBuff;                     // Rewind the pointer to beginning
            }
    
    //--- Example: Toggle GPIO18 so we can read it with the ADC ***/
    	if(DEBUG_TOGGLE == 1)
    	{
    		GpioDataRegs.GPATOGGLE.bit.GPIO18 = 1;		// Toggle the pin
    	}
    
    //--- Example: Toggle GPIO34 at a 0.5 sec rate (connected to the LED).
    //             (1/50000 sec/sample)*(1 samples/int)*(x interrupts/toggle) = (0.5 sec/toggle)
    //             ==> x = 25000
    	if(GPIO34_count++ > 25000)					// Toggle slowly to see the LED blink
    	{
    		GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1;	// Toggle the pin
    		GPIO34_count = 0;						// Reset the counter
    	}
    

  • Can you put a breakpoint in the ISR and see if it hits it?

    Your interrupt enables in InitAdca seem okay (although I don't think continuous mode is necessary). I'm guessing you've also writing your ISR address to the vector table and enabled interrupts globally (EINT) elsewhere in the code?

    As an experiment, can you try writing to PIEIFR to force the interrupt and see if that triggers it? That should help us narrow down the location of the issue.

    Whitney

  • I have done the following trials:

    1. I have put a breakpoint in ISR and found that it is not reaching ISR.

    2. I have looked for EINT and only found in Main.c

    3. I have forced PIEIFR by the following line but of no help. 

    //--- Enable the ADC interrupt
    	PieCtrlRegs.PIEIER1.bit.INTx1 = 1;			// Enable ADCA1 interrupt in PIE group 1
    	PieCtrlRegs.PIEIFR1.bit.INTx1 = 1;
    	IER |= 0x0FFF;								// Enable INT1 in IER to enable PIE group

    4. Since you said about enabled interrupt elsewhere I thought to make the same edits in lab 6 and found the code working. But the same edit done on lab 7 is not working.

    5. Then I commented InitEcap and excluded ecap from build as that was an addition in lab 7 from lab 6. But still it didn't work.

    Now I am really clueless about what is the mistake that I am not able to understand.

  • Even though the interrupt isn't occurring, if you look at the ADC result registers in the CCS Registers view, do you see their values changing? Can you see the ADC interrupt flag getting set?

    I'm trying to determine you aren't getting an interrupt because the conversion isn't happening or if you aren't getting an interrupt because the signal isn't propagating to the CPU. It sounds like it may be the latter since setting PIEIFR didn't work. Please double check the values of PIEIER1.INTx1, IER.INTx1, and ST1.INTM in the CCS Registers view.

    Whitney

  • Well as I see from the AdcBuf and AdcBuff arrays, only the first element of each reads actual value. From the second element they remain as initial which are zeros.

    *AdcBufPtr++ = 	AdcaResultRegs.ADCRESULT0;			// Read the result
    *AdcBuffPtr++ = AdcaResultRegs.ADCRESULT1;

  • Hi,

    The problem is solved. You were right. Actually, EPWM2 was set to trigger ADCSOCA. Then again it was reset and set to generate a PWM signal. The issue is solved. But I am facing another issue. I am now triggering SOC0 and SOC1 to convert ADCINA0 and ADCINA1 respectively with the help of EPWM2SOCA. I have generated EPWM4 signal. While trying to read the same EPWM signal from ADCINA0 and ADCINA1, I noticed that ADCINA0 is swinging full ie. from 0000 to 0FFF. But while trying to read from ADCINA1, it is swinging from 0000 to 0B7D. 

    Can you please explain?

  • Thanks for your patience. Have you made any progress figuring out the issue? If not, can you tell me what board you're using? Is it a LaunchPad, a controlCARD, or not a TI board?

    Thanks,

    Whitney

  • Please see the figures. The signal from EPWM1A is being read from both ADCA0 and ADCA1, which are triggered by common source EPWM3A. The first one is of ADCINA0 and second figure is of ADCINA1.

  • Dear Whitney,

    In continuation to early reply:

    I am using F28379D experimenter kit.

  • Hi Sayandev,

    Can you please try out below items:

            - Increase ACQPS to 2x the original value (the value is too low ~60ns SH). 

            - If increasing the ACQPS does not provide the full scale value of 0xFFF, can you move A1 connection to another ADC A channel?  Just wanted to see if A1 is being attenuated by something else.

    thanks and regards,

    Joseph

  • Hi Joseph,

    Thank you for your feedback.

    I have done as you said. But now I had following observations:

    1. ADCA0,ADCA1,ADCB0 were triggered from EPWM2SOCA. EPWM1A is being read from the pins. ADCA0 and ADCB0 reads fine. But ADCA1 reads attenuated values.

    2.ADCA0, ADCA1 and ADCA3 are triggered by EPWM2SOCA. EPWM1A is being read from the pins. ADCA0 and ADCA3 reads this.

    while ADCA1 reads

    3. While ADCA3 was given EPWM1A it reads as follows

    but when EPWM1 is read from ADCA1, ADCA3 reads as follows just as I connect pin49 EPWM1 to ADCA1 (pin11).

    I hope you got the problems. Please help. Thank you in advance.

  • Hi Sayandev,

    Let us first establish an external signal source other than EPWM output.  There is a 3.3V source on the board.  If you have access to common resistors and some jumper wires, try to create a voltage divider from it to feed to the ADC inputs.  Can you try this experiment?

            - Connect 2 resistors in series, first a 47ohm on the 3.3V supply.  On the other end of the 47ohm resistor, connect a 470ohm resistor to GND.   Do this connection only with the board powered off to minimize the risk of shorting the 3.3V supply.

           - Between the 47ohm and the 470ohm resistors,  You should get around 3V when the power is turned on, which is about the same level as the on-board VREFHI.  Jumper this junction to the ADC inputs you want to convert using the same EPWM trigger scheme that you have used.

           - Now see if ADCA0, ADCA1, ADCA3 and ADCB0 convert at full scale of 0xFFF

    If you are able to  run the experiments above, let me know the results.  Point of the exercise is to isolate if the issue you are seeing is due to the source or due to the ADC inputs.

    Regards,

    Joseph

  • Hi Joseph,

    I tried to do as you said. I tried to visualize the signals given from power supply from 0-3V to ADC through DAC. I am following the codes given in One day Workshop for F28379D. There I am using Lab7 project as reference and editing the same for desired outputs. In that code, Dacb is initialized. Hence I verified ADCA0, ADCB0 through it and it was performing satisfactorily. However I could not test ADCA1 as I am unable to initialize DACA. I just made changes in "DacbRegs" to "DacaRegs" keeping the bit values same. In the 'DefaultISR" file I too changed the register from 'DacbRegs" to "DacaRegs".

    void InitDacb(void)
    {
    	asm(" EALLOW");						// Enable EALLOW protected register access
    
    //--- Configure DAC-B control registers
        DacaRegs.DACCTL.all = 0x0001;
    // bit 15-8      0's:    reserved
    // bit 7-4    0000:      DAC PWMSYNC select, not used since LOADMODE=0
    // bit 3         0:      reserved
    // bit 2         0:      LOADMODE, DACVALA load mode, 0=next SYSCLK, 1=next PWMSYNC specified by SYNCSEL
    // bit 1         0:      reserved
    // bit 0         1:      DACREFSEL, DAC reference select, 0=VDAC/VSSA, 1=ADC VREFHI/VREFLO
    
    //--- Set DAC-B output to mid-range
        DacaRegs.DACVALS.all = 0x0000;         // DACVALS = bits 11-0, bits 15-12 reserved
    
    //--- Enable DAC-B output
        DacaRegs.DACOUTEN.bit.DACOUTEN = 1;    // DAC output enable, 0=disable, 1=enable
    
    //--- DAC-B lock control register
        DacaRegs.DACLOCK.all = 0x0000;         // Write a 1 to lock (cannot be cleared once set)
    
    	asm(" EDIS");						// Disable EALLOW protected register access
    
    } // end of InitDac()

    In default ISR, one line change:

    DacaRegs.DACVALS.all = AdcaResultRegs.ADCRESULT1;

    But no output is shown. What did I miss?

  • Hi  Sayandev,

    Sorry, i'm a bit confused from the details of your last response.  Have you tried just using the power supply to feed to the inputs of the ADCs in question?  You mentioned using the DAC as the signal source so i'm not sure if you ran the experiment with the power supply or the DAC.  To simplify things, let us just use the power supply for now, and move on to DAC if that part is still needed.

    Regards,

    Joseph 

  • Hi Joseph,

    I may have figured out the reason for having attenuated waveform in ADCA1. The fact is ADCA1 pin can be used as ADCA1 or DACB. In my program, I had actually used both DACB and ADCA1. Thus it may have been giving attenuated waveforms. I commented InitDacb() and ADCA1 starts reading well and good from 0 to 0x0FFF. If my analysis is correct, kindly confirm it.

    Thanks and Regards.

  • Hi Sanyandev.

    You are correct.  If you are enabling DACB while providing a separate signal on ADCA1, then there will be contention  as DACB output will also appear on ADCA1 pin.  this will be the reason why it would seem that you will have an attenuated signal on ADCA1 since DACB output is driving the pin as well.

    Regards,

    Joseph 

  • Hi Sayandev,

    Do you still have issues with this topic?

    Regards,

    Joseph

  • Hi Sayandev,

    Have not heard back from you on this issue so we're assuming that you have resolved your issue (i.e.-there is contention with DAC output to ADCINA0 and A1 channels when DAC output is active which appears to be the case in your code), hence marking this thread closed.  If you still have issues with this topic, please post it in the forum.

    Regards,

    Joseph