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.

TMS320F28335: Initiallizating ADC

Part Number: TMS320F28335
Other Parts Discussed in Thread: CONTROLSUITE

Hiii,

        I am working on C28x F28335 Delphino microcontroller, here I want to read ADC count values from all 16 channels of ADC(I am not using PWM trigger registers) and record the values in ADC ISR.

        Here I am using 25MHz ADC clock (SysCtrlRegs.HISPCP.all = 0x3) with sysclock 150Mhz here i am reading some value 473 as ADC count (at every channel, if i make    AdcRegs.ADCMAXCONV.all = 0x000; ) and while changed the register  as  AdcRegs.ADCMAXCONV.all = 0x0FFF not setting interrupts correctly  i.e., Problem is at ADC Initiallization and below is my attached code. 

//###########################################################################
//
// FILE: Example_2833xAdc.c
//
// TITLE: DSP2833x ADC Example Program.
//
// ASSUMPTIONS:
//
// This program requires the DSP2833x header files.
//
// Make sure the CPU clock speed is properly defined in
// DSP2833x_Examples.h before compiling this example.
//
// Connect signals to be converted to A2 and A3.
//
// As supplied, this project is configured for "boot to SARAM"
// operation. The 2833x Boot Mode table is shown below.
// For information on configuring the boot mode of an eZdsp,
// please refer to the documentation included with the eZdsp,
//
// $Boot_Table:
//
// GPIO87 GPIO86 GPIO85 GPIO84
// XA15 XA14 XA13 XA12
// PU PU PU PU
// ==========================================
// 1 1 1 1 Jump to Flash
// 1 1 1 0 SCI-A boot
// 1 1 0 1 SPI-A boot
// 1 1 0 0 I2C-A boot
// 1 0 1 1 eCAN-A boot
// 1 0 1 0 McBSP-A boot
// 1 0 0 1 Jump to XINTF x16
// 1 0 0 0 Jump to XINTF x32
// 0 1 1 1 Jump to OTP
// 0 1 1 0 Parallel GPIO I/O boot
// 0 1 0 1 Parallel XINTF boot
// 0 1 0 0 Jump to SARAM <- "boot to SARAM"
// 0 0 1 1 Branch to check boot mode
// 0 0 1 0 Boot to flash, bypass ADC cal
// 0 0 0 1 Boot to SARAM, bypass ADC cal
// 0 0 0 0 Boot to SCI-A, bypass ADC cal
// Boot_Table_End$
//
// DESCRIPTION:
//
// This example sets up the PLL in x10/2 mode.
//
// For 150 MHz devices (default)
// divides SYSCLKOUT by six to reach a 25.0Mhz HSPCLK
// (assuming a 30Mhz XCLKIN).
//
// For 100 MHz devices:
// divides SYSCLKOUT by four to reach a 25.0Mhz HSPCLK
// (assuming a 20Mhz XCLKIN).
//
// Interrupts are enabled and the ePWM1 is setup to generate a periodic
// ADC SOC on SEQ1. Two channels are converted, ADCINA3 and ADCINA2.
//
// Watch Variables:
//
// Voltage1[10] Last 10 ADCRESULT0 values
// Voltage2[10] Last 10 ADCRESULT1 values
// ConversionCount Current result number 0-9
// LoopCount Idle loop counter
//
//
//###########################################################################
//
// Original Author: D.F.
//
// $TI Release: 2833x/2823x Header Files and Peripheral Examples V133 $
// $Release Date: June 8, 2012 $
//###########################################################################

#include "DSP28x_Project.h" // Device Headerfile and Examples Include File

// Prototype statements for functions found within this file.
interrupt void adc_isr(void);

// Global variables used in this example:
Uint16 LoopCount;
Uint16 ConversionCount;
Uint16 Voltage1[10];
Uint16 Voltage2[10];
Uint16 Voltage3[10];
Uint16 Voltage4[10];
Uint16 Voltage5[10];
Uint16 Voltage6[10];
Uint16 Voltage7[10];
Uint16 Voltage8[10];
Uint16 Voltage9[10];

main()
{

// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP2833x_SysCtrl.c file.
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;

// Define ADCCLK clock frequency ( less than or equal to 25 MHz )
// Assuming InitSysCtrl() has set SYSCLKOUT to 150 MHz
EALLOW;
SysCtrlRegs.HISPCP.all = ADC_MODCLK;
EDIS;

// Step 2. Initialize GPIO:
// This example function is found in the DSP2833x_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 DSP2833x_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 DSP2833x_DefaultIsr.c.
// This function is found in DSP2833x_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
PieVectTable.ADCINT = &adc_isr;
EDIS; // This is needed to disable write to EALLOW protected registers

// Step 4. Initialize all the Device Peripherals:
// This function is found in DSP2833x_InitPeripherals.c
// InitPeripherals(); // Not required for this example
InitAdc(); // For this example, init the ADC

// Step 5. User specific code, enable interrupts:

// 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;

// Configure ADC
AdcRegs.ADCMAXCONV.all = 0x0FFF; // Setup all 16 conv's on SEQ1 // 0x000F - 0x00FF

// AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x7;
// AdcRegs.ADCMAXCONV.bit.MAX_CONV2 = 0x7;

AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; // Setup ADCINA0 as 1st SEQ1 conv.
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; // Setup ADCINA1 as 2nd SEQ1 conv.
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x2; // Setup ADCINA2 as 3rd SEQ1 conv.
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x3; // Setup ADCINA3 as 4th SEQ1 conv.

AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x4; // Setup ADCINA4 as 5th SEQ2 conv.
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x5; // Setup ADCINA5 as 6th SEQ2 conv.
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x6; // Setup ADCINA6 as 7th SEQ2 conv.
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x7; // Setup ADCINA7 as 8th SEQ2 conv.

AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 0x8; // Setup ADCINB0 as 9th SEQ3 conv.
AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 0x9; // Setup ADCINB1 as 10th SEQ3 conv
AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 0xA; // Setup ADCINB2 as 11th SEQ3 conv
AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 0xB; // Setup ADCINB3 as 12th SEQ3 conv

AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 0xC; // Setup ADCINB4 as 13th SEQ4 conv
AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 0xD; // Setup ADCINB5 as 14th SEQ4 conv
AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 0xE; // Setup ADCINB6 as 15th SEQ4 conv
AdcRegs.ADCCHSELSEQ4.bit.CONV15 = 0xF; // Setup ADCINB7 as 16th SEQ4 conv

// AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;// Enable SOCA from ePWM to start SEQ1
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1; // Enable software trigger for SEQ1( In separate instructions)

AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)

// AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ2 = 1;// Enable SOCB from ePWM to start SEQ2
AdcRegs.ADCTRL2.bit.RST_SEQ2 = 1; // Reset SEQ1
AdcRegs.ADCTRL2.bit.SOC_SEQ2 = 1; // // Enable software trigger for SEQ2 ( in separate instructions)

AdcRegs.ADCTRL2.bit.INT_ENA_SEQ2 = 1; // Enable SEQ2 interrupt (every EOS)
AdcRegs.ADCTRL1.bit.CONT_RUN = 1;

/*
// Assumes ePWM1 clock is already enabled in InitSysCtrl();
EPwm2Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group
EPwm2Regs.ETSEL.bit.SOCASEL = 1;//4; // Select SOC from from CPMA on upcount
EPwm2Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event

//SOCB
EPwm2Regs.ETSEL.bit.SOCBEN = 1; // Enable SOC on B group
EPwm2Regs.ETSEL.bit.SOCBSEL = 1;//4; // Select SOC from from CPMB on upcount
EPwm2Regs.ETPS.bit.SOCBPRD = 1; // Generate pulse on 1st event

EPwm2Regs.CMPA.half.CMPA = 0x0080; // Set compare A value
EPwm2Regs.TBPRD = 0xFFFF; // Set period for ePWM1
EPwm2Regs.TBCTL.bit.CTRMODE = 0; // count up and start

*/


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

}


interrupt void adc_isr(void)
{

Voltage1[ConversionCount] = AdcRegs.ADCRESULT0 >>4;
Voltage2[ConversionCount] = AdcRegs.ADCRESULT1 >>4;
Voltage3[ConversionCount] = AdcRegs.ADCRESULT2 >>4;
Voltage4[ConversionCount] = AdcRegs.ADCRESULT3 >>4;
Voltage5[ConversionCount] = AdcRegs.ADCRESULT4 >>4;
Voltage6[ConversionCount] = AdcRegs.ADCRESULT5 >>4;
Voltage7[ConversionCount] = AdcRegs.ADCRESULT6 >>4;
Voltage8[ConversionCount] = AdcRegs.ADCRESULT7 >>4;
Voltage9[ConversionCount] = AdcRegs.ADCRESULT8 >>4;


// 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
AdcRegs.ADCTRL2.bit.RST_SEQ2 = 1; // Reset SEQ1
AdcRegs.ADCST.bit.INT_SEQ2_CLR = 1; // Clear INT SEQ1 bit
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE

return;
}

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void InitAdc(void)
{
extern void DSP28x_usDelay(Uint32 Count);

EALLOW;
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;
ADC_cal();
EDIS;

AdcRegs.ADCTRL3.all = 0x00E0; // Power up bandgap/reference/ADC circuits
DELAY_US(ADC_usDELAY); // Delay before converting ADC channels

}

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------

and above is my Initiallization of ADC. plese get me out of this.

Thanks in Advance.

  

  • Hi Narasimha,

    The best way to accomplish this is probably to start with this example in ControlSUITE:

    \controlSUITE\device_support\f2833x\v142\DSP2833x_examples_ccsv5\adc_seqmode_test

    Get this example working first, and then modify it to meet your needs, re-testing to ensure it has not been broken whenever possible.

    It is converting forever in continuous run mode. To get it to do what you want, I think you need to modify it to:
    -Use 16 channels instead of 1
    -Use an interrupt to read the results instead of a spin-wait loop
  • Hi Devin,
    I went through the example code (adc_seqmode_test.c) while iam running this code i am getting continuously 473 count value instead of zero, is there any problem at initiallization? i.e., i took ADC clock at 25MHz and i took AdcRegs.ADCTRL3.all = 0x00E0;

    Regards,
    Narasimha
  • Hi Narasimha,

    What voltage is being input to the channel? If you grounded the channel, something near 0 would be expected. If it is floating then 473 could be a reasonable conversion result.

    If you aren't getting good results with the in-built example, I'd suggest troubleshooting the HW to make sure all the supply and reference voltages and pins are as expected. What HW are you using? Is it a TI kit or custom board?
  • HI Davin,

                 I am using the custom board, 

    Here is my Hardware configuration for ADC,

               ADCLO AND ADCREFIN are set to ground,

               ADCRESEXT pull down with 20k ohm,

              ADCREFP,ADCREFM are shorted and set that to ground with 100nF

             all ADC channels are set to ground

    and here is my Schm  design for ADC

    Regards,

    Narsimha.

  • Hi Narsimha,

    I don't think you can tie REFP and REFM together; they should have different voltages.

    They should also have a 2.2uF each instead of a 100nF shared capacitor to ground.

    See

  • Actually, why are you trying to initialize the ADC and sample that channels at all if all the ADC inputs are tied to ground?
  • Hi Devin,

          I am in vacation sorry for the delay, in my project i am using internal reference voltage for that we did schematic and here, all the Input pins are said to ground(my new custom board is not arrived yet). Hence, i am working on this board with respective schematic.

         If i run the example code(adc_seqmode_test) from controlsuite, i cannot convert the zero volts (ground) properly,is there any issue?

    Regards,

    Narasimha

  • Hi Narasimha,

    The erratic conversion results are expected in this case since the ADC HW is configured to disable the ADC.