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.

TMS320F28069: ADC Ping Pong/Continuous Sampling on F28069

Part Number: TMS320F28069
Other Parts Discussed in Thread: CONTROLSUITE

Hi,

We are trying to test ADC Ping Pong/Continuous Sampling on F28069(EVM).

We tried to import the sample code for F2802x from the below website.
e2e.ti.com/.../2060564

But this code doesn't work with F28069, ADC is not able to sample the input signal....
Please let me know if there is anything else to be added or modified to the below above source code to work on F28069?

void Adc_Config(void);
void setup_adc(void);
void take_samples(Uint16, Uint16*);

// Global variables used in this example:
Uint16 bufferA[100];


main()
{

   #ifdef _FLASH
    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
   #endif

// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the f2802x_SysCtrl.c file.
   InitSysCtrl();

// Step 2. Initialize GPIO:
// This example function is found in the f2802x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio();  // Skipped for this example

// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
   DINT;

// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the f2802x_PieCtrl.c file.
   InitPieCtrl();

// Disable CPU interrupts and clear all CPU interrupt flags:
   IER = 0x0000;
   IFR = 0x0000;

// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example.  This is useful for debug purposes.
// The shell ISR routines are found in f2802x_DefaultIsr.c.
// This function is found in f2802x_PieVect.c.
   InitPieVectTable();

// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
   EALLOW;  // This is needed to write to EALLOW protected register

   EDIS;    // This is needed to disable write to EALLOW protected registers
   // Step 4. Initialize all the Device Peripherals:
      InitAdc();  // For this example, init the ADC
      AdcOffsetSelfCal();

   // Step 5. User specific code, enable interrupts:
   // Enable ADCINT1 in PIE
      PieCtrlRegs.PIEIER1.bit.INTx1 = 1;   // Enable INT 1.1 in the PIE
      IER |= M_INT1;                       // Enable CPU Interrupt 1
      EINT;                                // Enable Global interrupt INTM
      ERTM;                                // Enable Global realtime interrupt DBGM

   //Function call to setup ADC for ping pong
      setup_adc();



      for(;;) //call sample function repeatedly every 50000us.
      {
          //take_samples(100,bufferA,bufferB);
          take_samples(100,bufferA);
          DELAY_US(50000);
      }
   }

void setup_adc()
{
    // enable bandgap, clocks, powerup etc.

    EALLOW;
    AdcRegs.ADCCTL2.bit.CLKDIV2EN = 1;   /* Set ADC clock division */
    AdcRegs.ADCCTL2.bit.CLKDIV4EN = 0;   /* Set ADC clock division */
    //set all SOCs to point channel A4
    AdcRegs.ADCCTL2.bit.ADCNONOVERLAP = 0;/* Set ADCNONOVERLAP contorl bit to  Allowed */
    AdcRegs.ADCSOC0CTL.bit.CHSEL = 4;    /* Set SOC0 channel select to ADCINA4*/
    AdcRegs.ADCSOC1CTL.bit.CHSEL = 4;    /* Set SOC1 channel select to ADCINA4*/
    AdcRegs.ADCSOC2CTL.bit.CHSEL = 4;    /* Set SOC2 channel select to ADCINA4*/
    AdcRegs.ADCSOC3CTL.bit.CHSEL = 4;    /* Set SOC3 channel select to ADCINA4*/
    AdcRegs.ADCSOC4CTL.bit.CHSEL = 4;    /* Set SOC4 channel select to ADCINA4*/
    AdcRegs.ADCSOC5CTL.bit.CHSEL = 4;    /* Set SOC5 channel select to ADCINA4*/
    AdcRegs.ADCSOC6CTL.bit.CHSEL = 4;    /* Set SOC6 channel select to ADCINA4*/
    AdcRegs.ADCSOC7CTL.bit.CHSEL = 4;    /* Set SOC7 channel select to ADCINA4*/
    AdcRegs.ADCSOC8CTL.bit.CHSEL = 4;    /* Set SOC8 channel select to ADCINA4*/
    AdcRegs.ADCSOC9CTL.bit.CHSEL = 4;    /* Set SOC9 channel select to ADCINA4*/
    AdcRegs.ADCSOC10CTL.bit.CHSEL = 4;    /* Set SOC10 channel select to ADCINA4*/
    AdcRegs.ADCSOC11CTL.bit.CHSEL = 4;    /* Set SOC11 channel select to ADCINA4*/
    AdcRegs.ADCSOC12CTL.bit.CHSEL = 4;    /* Set SOC12 channel select to ADCINA4*/
    AdcRegs.ADCSOC13CTL.bit.CHSEL = 4;    /* Set SOC13 channel select to ADCINA4*/
    AdcRegs.ADCSOC14CTL.bit.CHSEL = 4;    /* Set SOC14 channel select to ADCINA4*/
    AdcRegs.ADCSOC15CTL.bit.CHSEL = 4;    /* Set SOC15 channel select to ADCINA4*/

    //Set minimum acquisition time of 7 cycles on each SOC
    AdcRegs.ADCSOC0CTL.bit.ACQPS = 6;    /* Set SOC0 S/H Window to 7 ADC Clock Cycles*/
    AdcRegs.ADCSOC1CTL.bit.ACQPS = 6;    /* Set SOC1 S/H Window to 7 ADC Clock Cycles*/
    AdcRegs.ADCSOC2CTL.bit.ACQPS = 6;    /* Set SOC2 S/H Window to 7 ADC Clock Cycles*/
    AdcRegs.ADCSOC3CTL.bit.ACQPS = 6;    /* Set SOC3 S/H Window to 7 ADC Clock Cycles*/
    AdcRegs.ADCSOC4CTL.bit.ACQPS = 6;    /* Set SOC4 S/H Window to 7 ADC Clock Cycles*/
    AdcRegs.ADCSOC5CTL.bit.ACQPS = 6;    /* Set SOC5 S/H Window to 7 ADC Clock Cycles*/
    AdcRegs.ADCSOC6CTL.bit.ACQPS = 6;    /* Set SOC6 S/H Window to 7 ADC Clock Cycles*/
    AdcRegs.ADCSOC7CTL.bit.ACQPS = 6;    /* Set SOC7 S/H Window to 7 ADC Clock Cycles*/
    AdcRegs.ADCSOC8CTL.bit.ACQPS = 6;    /* Set SOC8 S/H Window to 7 ADC Clock Cycles*/
    AdcRegs.ADCSOC9CTL.bit.ACQPS = 6;    /* Set SOC9 S/H Window to 7 ADC Clock Cycles*/
    AdcRegs.ADCSOC10CTL.bit.ACQPS = 6;    /* Set SOC10 S/H Window to 7 ADC Clock Cycles*/
    AdcRegs.ADCSOC11CTL.bit.ACQPS = 6;    /* Set SOC11 S/H Window to 7 ADC Clock Cycles*/
    AdcRegs.ADCSOC12CTL.bit.ACQPS = 6;    /* Set SOC12 S/H Window to 7 ADC Clock Cycles*/
    AdcRegs.ADCSOC13CTL.bit.ACQPS = 6;    /* Set SOC13 S/H Window to 7 ADC Clock Cycles*/
    AdcRegs.ADCSOC14CTL.bit.ACQPS = 6;    /* Set SOC14 S/H Window to 7 ADC Clock Cycles*/
    AdcRegs.ADCSOC15CTL.bit.ACQPS = 6;    /* Set SOC15 S/H Window to 7 ADC Clock Cycles*/


    //ADCINT 1 and 2 enabled
    AdcRegs.INTSEL1N2.bit.INT1E = 1;        /* Enable/Disable ADCINT1 interrupt */
    AdcRegs.INTSEL1N2.bit.INT2E = 1;        /* Enable/Disable ADCINT2 interrupt */
    //ADCINT 1 and 2 wait for confirmation
    AdcRegs.INTSEL1N2.bit.INT1CONT = 0;        /* Enable/Disable ADCINT1 Continuous mode */
    AdcRegs.INTSEL1N2.bit.INT2CONT = 0;        /* Enable/Disable ADCINT2 Continuous mode */
    //SOC 6 will trigger ADCINT1
    AdcRegs.INTSEL1N2.bit.INT1SEL = 6;        /* setup EOC6 to trigger ADCINT1 to fire */
    //SOC 14 will trigger ADCINT2
    AdcRegs.INTSEL1N2.bit.INT2SEL = 14;        /* setup EOC14 to trigger ADCINT2 to fire */

    //ADCINT2 will trigger first 8 SOCs
    AdcRegs.ADCINTSOCSEL1.bit.SOC0 = 2;        /* SOCx ADCINT2 Interrupt Trigger Select.*/
    AdcRegs.ADCINTSOCSEL1.bit.SOC1 = 2;
    AdcRegs.ADCINTSOCSEL1.bit.SOC2 = 2;        /* SOCx ADCINT2 Interrupt Trigger Select.*/
    AdcRegs.ADCINTSOCSEL1.bit.SOC3 = 2;
    AdcRegs.ADCINTSOCSEL1.bit.SOC4 = 2;        /* SOCx ADCINT2 Interrupt Trigger Select.*/
    AdcRegs.ADCINTSOCSEL1.bit.SOC5 = 2;
    AdcRegs.ADCINTSOCSEL1.bit.SOC6 = 2;        /* SOCx ADCINT2 Interrupt Trigger Select.*/
    AdcRegs.ADCINTSOCSEL1.bit.SOC7 = 2;

    //ADCINT1 will trigger second 8 SOCs
    AdcRegs.ADCINTSOCSEL2.bit.SOC8 = 1;        /* SOCx ADCINT1 Interrupt Trigger Select.*/
    AdcRegs.ADCINTSOCSEL2.bit.SOC9 = 1;
    AdcRegs.ADCINTSOCSEL2.bit.SOC10 = 1;    /* SOCx ADCINT1 Interrupt Trigger Select.*/
    AdcRegs.ADCINTSOCSEL2.bit.SOC11 = 1;
    AdcRegs.ADCINTSOCSEL2.bit.SOC12 = 1;    /* SOCx ADCINT1 Interrupt Trigger Select.*/
    AdcRegs.ADCINTSOCSEL2.bit.SOC13 = 1;
    AdcRegs.ADCINTSOCSEL2.bit.SOC14 = 1;    /* SOCx ADCINT1 Interrupt Trigger Select.*/
    AdcRegs.ADCINTSOCSEL2.bit.SOC15 = 1;
    EDIS;
}

void take_samples(Uint16 sample_size, Uint16* buffer)
{
    Uint16 index = 0;

    //enable adcint1 and adcint2 needed for ping-pong sampling
    AdcRegs.INTSEL1N2.bit.INT1E = 1;        /* Enable/Disable ADCINT1 interrupt */
    AdcRegs.INTSEL1N2.bit.INT2E = 1;        /* Enable/Disable ADCINT2 interrupt */

    AdcRegs.ADCSOCFRC1.all = 0x00FF; //software force SOC pending flag for first 8 SOCs
    while(index < sample_size) {
        while (AdcRegs.ADCINTFLG.bit.ADCINT1 == 0){/*wait and do nothing*/}
        AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear ADCINT1

        //ADCINT1 was triggered by the end of SOC6.
        //Since they are done, read SOC0-SOC7 into buffer
        //(this assumes SOC7 will be done converting by
        //the time the code reaches it to put in buffer).
        //Also note that SOC6 triggered ADCINT1 which
        //then triggered SOC8-SOC15 to be pending.
        //These newly pending SOCs will begin converting
        //immediately after SOC7 finishes.

        buffer[index++] = AdcResult.ADCRESULT0;
        buffer[index++] = AdcResult.ADCRESULT1;
        buffer[index++] = AdcResult.ADCRESULT2;
        buffer[index++] = AdcResult.ADCRESULT3;
        buffer[index++] = AdcResult.ADCRESULT4;
        buffer[index++] = AdcResult.ADCRESULT5;
        buffer[index++] = AdcResult.ADCRESULT6;
        buffer[index++] = AdcResult.ADCRESULT7;

        while (AdcRegs.ADCINTFLG.bit.ADCINT2 == 0){/*wait and do nothing*/}
        AdcRegs.ADCINTFLGCLR.bit.ADCINT2 = 1; //clear ADCINT2

        //ADCINT2 was triggered by the end of SOC14.
        //Since they are done, read SOC8-SOC15 into buffer
        //(this assumes SOC15 will be done converting by
        //the time the code reaches it to put in buffer).
        //Also note that SOC14 triggered ADCINT2 which
        //then triggered SOC0-SOC7 to be pending.
        //These newly pending SOCs will begin converting
        //immediately after SOC15 finishes.

        buffer[index++] = AdcResult.ADCRESULT8;
        buffer[index++] = AdcResult.ADCRESULT9;
        buffer[index++] = AdcResult.ADCRESULT10;
        buffer[index++] = AdcResult.ADCRESULT11;
        buffer[index++] = AdcResult.ADCRESULT12;
        buffer[index++] = AdcResult.ADCRESULT13;
        buffer[index++] = AdcResult.ADCRESULT14;
        buffer[index++] = AdcResult.ADCRESULT15;
    }

    //disable adcint1 and adcint2 to STOP the ping-pong sampling
    AdcRegs.INTSEL1N2.bit.INT1E = 0;
    AdcRegs.INTSEL1N2.bit.INT2E = 0;
}

Best Regards
Kummi

  • Hi Kummi,

    How exactly does the ADC fail to sample the signal? Does the software hang at some point? Is a signal sampled, but it isn't as expected? Are the conversion results all 0's?

    What signal source are you using to drive into the device? Have you verified that you can sample this using one of the other ADC examples in ControlSUITE?
  • Hi Devin,

    Thank you.

    Currently we are trying to input 0V by shorting the inputs to GND,
    but we are getting random values instead of "0".
    ADC Example codes meant for F28069 from ControlSuite works fine.

    Best Regards
    Kummi
  • Hi Kummi,

    If you use a different ControlSUITE ADC example, are you able to get good conversion results on channel A4? This would probably be a good place to start.
  • Hi Devin,

    Thank you.

    It works with a different F28069 example code but problem with the Continuous Sampling code.
    It seems the code is struck at "__interrupt void ADCINT1_ISR(void)".Tried to comment out the
    for loop and found out that actual ADC input is not being reflected in the register.

    Could you please let me know if there is any working example code for
    Ping Pong/Continuous Sampling on F28069?

    Best Regards
    Kummi
  • Hi Devin,

    Tried with A4 and A2 channels (F28069 Example Code from controsuite).
    Getting proper conversion result 0V if we connect/short the input to GND.

    Please let me know if there is any working example code for
    Ping Pong/Continuous Sampling on F28069?
  • any suggestions?
  • Hi Kummi,

    Continuous conversion shouldn't be using an ISR; the datarate is too high so the CPU should be directly collecting the data.  This appears to be the case in the code above, but not in your comment about the code being stuck in the "__interrupt void ADCINT1_ISR(void)"  ISR.