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.

ADC Problem on TMS320F28335

Other Parts Discussed in Thread: TMS320F28335

We are developing with the DSP TMS320F28335 PGF controlCARD Release 1.0 (and USB-EMU R3 docking station) and we are having trouble reading the ADC.

We tried using the sample code from the "C2833x C/C++ Header Files and Peripheral Examples" and we are still getting unexpected values from the ADC.

We are using the Example_2833xAdcSoc.c (ADC SOC example), and we have put a 1V DC voltage on ADC A3. According to the documentation - we should see a value of 1365 (4096 * 1 / 3) in the  ADCMIRROR.ADCRESULT_MIRROR0 register.... However we get a values of between 37 and 85.

Furthermore - if we change the code to use a different channel we get different values again, even though the voltage is the same.
What am I missing? Any 28x ADC experts out there...Can anyone suggest what my issue could be?

I've included my register values (after ACDRESULT_MIRROR is read) and code listing below FYI.

Thanks in Advance.

ADCTRL1 = 0x0000
ADCTRL2 = 0x0900
ADCTRL3 = 0x00E0
ADCST = 0x0001
ADCMAXCONV = 0x0000
ADCCHSELSEQ1 = 0x0003
ADCASEQSR = 0x0001
ADCREFSEL = 0x1B1D
ADCOFFTRIM = 0x0009
ADCRESULT = 0x0450
ADCRESULT_MIRROR_0 = 0x0045

main()
{

   InitSysCtrl();

   EALLOW;
   #if (CPU_FRQ_150MHZ)     // Default - 150 MHz SYSCLKOUT
     #define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3)   = 25.0 MHz
   #endif
   #if (CPU_FRQ_100MHZ)
     #define ADC_MODCLK 0x2 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2)   = 25.0 MHz
   #endif
   EDIS;

   DINT;
   InitPieCtrl();

   IER = 0x0000;
   IFR = 0x0000;
   InitPieVectTable();

   EALLOW;  // This is needed to write to EALLOW protected register
   PieVectTable.ADCINT = &adc_isr;
   EDIS;    // This is needed to disable write to EALLOW protected registers

   InitAdc();  // For this example, init the ADC

// Enable ADCINT in PIE
   PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
   IER |= M_INT1; // Enable CPU Interrupt 1
   EINT;          // Enable Global interrupt INTM
   ERTM;          // Enable Global realtime interrupt DBGM

   LoopCount = 0;
   ConversionCount = 0;
   
   AdcRegs.ADCMAXCONV.all = 0x0000;       // Setup 1 conv's on SEQ1
   AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x3; // Setup ADCINA3 as 1st SEQ1 conv.
   AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;// Enable SOCA from ePWM to start SEQ1
   AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;  // Enable SEQ1 interrupt (every EOS)

// Assumes ePWM1 clock is already enabled in InitSysCtrl();
   EPwm1Regs.ETSEL.bit.SOCAEN = 1;        // Enable SOC on A group
   EPwm1Regs.ETSEL.bit.SOCASEL = 4;       // Select SOC from from CPMA on upcount
   EPwm1Regs.ETPS.bit.SOCAPRD = 1;        // Generate pulse on 1st event
   EPwm1Regs.CMPA.half.CMPA = 0x0080;      // Set compare A value
   EPwm1Regs.TBPRD = 0xFFFF;              // Set period for ePWM1
   EPwm1Regs.TBCTL.bit.CTRMODE = 0;          // count up and start

// Wait for ADC interrupt
   for(;;)
   {
      LoopCount++;
   }

}


interrupt void  adc_isr(void)
{

  Voltage1[ConversionCount] = AdcMirror.ADCRESULT0;

  // If 40 conversions have been logged, start over
  if(ConversionCount == 9)
  {
     ConversionCount = 0;
  }
  else ConversionCount++;

  // Reinitialize for next ADC sequence
  AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;         // Reset SEQ1
  AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;       // Clear INT SEQ1 bit
  PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE

  return;
}


  • Paul- do you see the same conversion results no matter what voltage is on the input?  I have duplicated a similar problem but always see conversions around 400-500.  I'll keep you posted as I debug, but you may want to watch the following post as well:

    http://e2e.ti.com/support/microcontrollers/tms320c2000_32-bit_real-time_mcus/f/171/t/161012.aspx#593027

  • Hi, thanks for you help.

    Our observations were:

    1) Some channels behaved differently than others (even if same voltage applied)

    2) On some channels ADC value decreased towards zero when voltage increased to about 1.280 volts

    3) We expected the output to be fairly steady with a little bit of random noise, but it appeared that the output was always one of 6 values: 0x25,0x25,0x45,0x55,0x70,0x74 - with a constant 1 volt input.

    Please let us know if you make a breakthough - this is still an issue for us.

    thanks in advance.

  • Paul,

    in your first post you showed register ADCTRL3 to be 0x00E0. This init value will set the ADC's FCLK = HSPCLK, which is far above the maximum of 25MHz. Where in your code do you initialize bits 4-1 of ADCTRL3? Also, SPRU812 recommends to keep FCLK below 12.5MHz to reduce the impact of the integral nonlinearity error (INL).

     

     

  • Paul- I think Frank has hit it.  0x00E0 is OK for ADCTRL3 assuming the HSPCLK has been divided down like the example in the user guide.  It looks like the other adc examples correctly modify the HSPCLK divider but somehow it was missed in this one.  I suggest modifying the code as follows:

    EALLOW;
       #if (CPU_FRQ_150MHZ)     // Default - 150 MHz SYSCLKOUT
         #define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3)   = 25.0 MHz
       #endif
       #if (CPU_FRQ_100MHZ)
         #define ADC_MODCLK 0x2 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2)   = 25.0 MHz
       #endif

    // Specific clock setting for this example:
       SysCtrlRegs.HISPCP.all = ADC_MODCLK;    // HSPCLK = SYSCLKOUT/ADC_MODCLK                  <=== ADD THIS LINE
       EDIS;

    Frank- thanks for the help

    BTW I have submitted a bug report to fix the example code.

  • Frank, Joe,

    Your solution works for me:

      SysCtrlRegs.HISPCP.all = ADC_MODCLK;

    I now get output of 0x000 to 0xFFF for the full range of 0 to 3V dc.

    Many hanks for your help !!

  • Frank,

    I'm confused by your post regarding the setting of ADCTRL3 to be 0x00E0 that "will set the ADC's FLCK."

    According to the ADC datasheet, ADCTRL1, not ADCTRL3, sets the ADC's FLCK.

    Does this make a difference? If so, does the solution to the problem change?

  • Paul,

    I think the actual bug in the code is the setting of ADCTRL1 to 0x000, ( NOT ADCTRL3 to 0x00E0),  which sets the CPS bit to 0, which results in ADCCLK = FCLK/1.

    According to the ADC datasheet, ADCTRL1 sets the CPS bit which controls the ADCCLK. ADCTRL3  does not control the FCLK.