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.

TMS210F2812 ADC does not work

Other Parts Discussed in Thread: TMS320F2812

Hello,

There are very odd things happening with the ADC of the TMS320F2812. A few weeks ago, I was able to get it to work and convert signals with it. Running the very same code now, the device only produces useless results.

With the code that I attached below, that mainly sets up the ADC and the timer that triggers it, the results are always something like
1764
1764
1796
1764
1764
1764
1764
1796
1796
1788
1764
1764
1764
1756
1796
1764
1756
1764
1788
1764
1764
1764
1764
1756
1796
1796
1788
1764
1764
Conversion results similar to these appear regardless of the input voltage.

Running the provided ADC example project did not quite work. Apparently the project folders are lacking some required files or the configuration is not proper. Therefore I used the main source code file from the example project folder and inserted it into the project environment that I use for all my code (other programs work). With the evaluation board that I usually use, the results are just as before: seemingly random values in the vicinity of 1780 this time. This happens regardless of the applied voltage (from a DC power supply), or whether the input is short-circuited.

Trying two other boards, the results were always zero, voltage there or not.

Given that the source code used to work and the provided sample code does not, one could think that the processor must have broken in the meantime. On the other hand, it would be strange if all three available evaluation boards (eZdsp) including their processors are faulty. What could be the issue here?

Regards,

Adrian

/*
 * main.c
 *
 * uses ADC to sample ADCINA0
 *
 * use GP timer 1 of event manager A to provide a time base of f = 1 kHz for sampling
 * input pin for signal: ADCINA0 (analog interface: top left pin, GND: bottom line of pins)
 * output pin for sampling pulse (just to check): T1PWM (I/O pin 15, bottom row eighth pin)
 */
#include "DSP281x_Device.h"            // define CPU commands, variable types, include all peripheral header files
#include "DSP281x_Examples.h"        // define CPU clock, include various header files
#include "math.h"
//extern void DSP28x_usDelay(Uint32 Count);
interrupt void adc_isr();

volatile unsigned int ADCcount=0;
unsigned int N=300;    // no. of samples to save
volatile unsigned int value[300];


void main() {

//============= system control ==============================================================================

//    InitSysCtrl();            // disable watchdog timer, initialize PLL, configure clocks
EALLOW;
    SysCtrlRegs.WDCR=0x0068;            // disable watchdog timer
    InitPll(0xA);                        // set clock PLL to 10: SYSCLKOUT = 5*XCLKIN = 150 MHz
    SysCtrlRegs.HISPCP.all=0x0000;        // set high-speed peripheral clock pre-scaler, factor 1
    SysCtrlRegs.LOSPCP.all=0x0002;        // set low-speed peripheral clock pre-scaler
    SysCtrlRegs.PCLKCR.bit.EVAENCLK=1;    // enable peripheral clock for event manager A
    SysCtrlRegs.PCLKCR.bit.ADCENCLK=1;    // enable peripheral clock for ADC
EDIS;

//============= GPIO pins ===================================================================================

// configure all GPIO pins as digital outputs and set to 0
EALLOW;
    GpioMuxRegs.GPAMUX.all=0;
    GpioMuxRegs.GPBMUX.all=0;
    GpioMuxRegs.GPDMUX.all=0;
    GpioMuxRegs.GPEMUX.all=0;
    GpioMuxRegs.GPFMUX.all=0;
    GpioMuxRegs.GPGMUX.all=0;
    GpioMuxRegs.GPADIR.all=0xFFFF;
    GpioMuxRegs.GPBDIR.all=0xFFFF;
    GpioMuxRegs.GPDDIR.all=0xFFFF;
    GpioMuxRegs.GPEDIR.all=0xFFFF;
    GpioMuxRegs.GPFDIR.all=0xFFFF;
    GpioMuxRegs.GPGDIR.all=0xFFFF;
    GpioDataRegs.GPACLEAR.all=0xFFFF;
    GpioDataRegs.GPBCLEAR.all=0xFFFF;
    GpioDataRegs.GPDCLEAR.all=0xFFFE;
    GpioDataRegs.GPECLEAR.all=0xFFFF;
    GpioDataRegs.GPFCLEAR.all=0xFFFF;
    GpioDataRegs.GPGCLEAR.all=0xFFFF;
// configure required GPIO pins as peripheral (here: timer) outputs (digital I/O)
    GpioMuxRegs.GPAMUX.bit.T1PWM_GPIOA6=1;
EDIS;

//============= timers ======================================================================================

    float d=0.1;
// GP timer 1 setup -- provides time base for ADC
    EvaRegs.T1CON.bit.FREE=1;        // keep going on emulation suspend bec. ADC still finishes sequence
    EvaRegs.T1CON.bit.SOFT=1;        // ... second part of it
    EvaRegs.T1CON.bit.TMODE=2;        // continuous up-counting mode
    EvaRegs.T1CON.bit.TPS=0;        // input clock prescaler
    EvaRegs.T1CON.bit.TENABLE=1;    // enable timer
    EvaRegs.T1CON.bit.TCLKS10=0;    // use HSPCLK as clock
    EvaRegs.T1CON.bit.TCLD10=0;        // reload compare register T1CMPR at beginning of switching period
    EvaRegs.T1CON.bit.TECMPR=1;        // enable timer compare

    EvaRegs.T1PR=0x1FFF;
    EvaRegs.T1CMPR=EvaRegs.T1PR*d;    // compare register for GP T1
    EvaRegs.T1CNT=0;                // initialize counter register

// GP timer control register of EVA (for T1PWM)
    EvaRegs.GPTCONA.bit.T1CTRIPE=0;    // disable trip function that can drive output to high Z
    EvaRegs.GPTCONA.bit.TCMPOE=1;    // enable compare output
    EvaRegs.GPTCONA.bit.T1TOADC=2;    // start ADC on period match
    EvaRegs.GPTCONA.bit.TCMPOE=1;    // enable timer compare outputs
    EvaRegs.GPTCONA.bit.T1CMPOE=1;    // enable timer 1 compare outputs
    EvaRegs.GPTCONA.bit.T1PIN=1;    // polarity of T1PWM (1 = active L, 2 = active H)

//============= ADC =========================================================================================

    AdcRegs.ADCTRL1.bit.RESET=1;        // reset ADC
    asm(" RPT #50 || NOP");                // required delay after reset before modifying ADC registers
    //InitAdc();                            // power up ADC
    AdcRegs.ADCTRL3.bit.ADCBGRFDN=0x3;    // power up bandgap/reference circuitry
    for (i=0;i<2500;i++) asm(" RPT #255 || NOP");    // required 5 ms delay (5.1 ms)
    AdcRegs.ADCTRL3.bit.ADCPWDN=1;        // power up rest of ADC
    for (i=0;i<20;i++) asm(" RPT #255 || NOP");        // required 20 us delay (38 us)
    //DELAY_US(20L);

    AdcRegs.ADCTRL1.bit.SUSMOD=1;        // upon emulation suspend finish ADC sequence
    AdcRegs.ADCTRL1.bit.ACQ_PS=15;        // length of the S/H pulse in ADC clock cycles, max. value 15
    AdcRegs.ADCTRL1.bit.CPS=1;            // core clock prescaler, factor 1
    AdcRegs.ADCTRL1.bit.CONT_RUN=0;        // start-stop mode (as opposed to continuous conversion)
    AdcRegs.ADCTRL1.bit.SEQ_OVRD=0;        // disable sequencer override, NR
    AdcRegs.ADCTRL1.bit.SEQ_CASC=0;        // dual sequencer mode (as opposed to cascaded mode)
    AdcRegs.ADCTRL2.bit.RST_SEQ1=1;        // reset sequencer 1
    AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=1;    // enable interrupt request by SEQ1
    AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1=0;    // interrupt after every EOS (as opposed to every second one)
    AdcRegs.ADCTRL2.bit.EVA_SOC_SEQ1=1;    // allow event manager A to start conversion sequence
    AdcRegs.ADCTRL3.bit.ADCEXTREF=0;    // use internal reference sources
    //AdcRegs.ADCTRL3.bit.ADCCLKPS=3;        // core clock divider, factor 1/6 to get ADCLK to 25 MHz
    AdcRegs.ADCTRL3.bit.ADCCLKPS=15;    // core clock divider, f_ADCCLK = 150 MHz / [2*ADCCLKPS*(CPS+1)]
    AdcRegs.ADCTRL3.bit.SMODE_SEL=0;    // sequential sampling mode (as opposed to simultaneous)
    AdcRegs.ADCMAXCONV.bit.MAX_CONV1=0;    // # of conversions in autoconversion session of SEQ1 = 1
    AdcRegs.ADCCHSELSEQ1.bit.CONV00=0;    // sample ADCINA0
    AdcRegs.ADCST.bit.INT_SEQ1_CLR=1;    // clear SEQ1 interrupt flag bit

//============= interrupts ==================================================================================

    //DINT;    // disable CPU interrupts
// configure interrupt control and peripheral interrupt expansion table
    InitPieCtrl();                        // clear all PIEIER and PIEIFR registers
    IER = 0x0000;                        // disable all interrupts on CPU level
    IFR = 0x0000;                        // clear CPU IR flag register
    InitPieVectTable();                    // initialize and enable PIE vector table
EALLOW;
    PieVectTable.ADCINT=&adc_isr;
EDIS;
    IER |= M_INT1;                        // enable CPU IR group 1
    EnableInterrupts();                    // enable interrupts globally, enable PIE vector table, clear PIEACK
    PieCtrlRegs.PIEIER1.bit.INTx6=1;    // enable ADCINT
    ERTM;                                // clear DBGM (debug enable mask bit): service halt requests and
                                        // breakpoints, allow emulator to access registers in real time


//============= infinite loop ===============================================================================

     while(1){}
}


interrupt void adc_isr(){

    value[ADCcount]=AdcRegs.ADCRESULT0>>4;    // shr bec. 12-bit value is left-aligned in 16-bit register
    //v_d=value/4095*3*500;                    // convert conversion result to voltage
    AdcRegs.ADCTRL2.bit.RST_SEQ1=1;            // reset sequencer 1
    AdcRegs.ADCST.bit.INT_SEQ1_CLR=1;        // clear SEQ1 interrupt flag bit
    PieCtrlRegs.PIEACK.all=PIEACK_GROUP1;    // clear acknowledge bit for group 1

    if (ADCcount==N-1){
        ADCcount=0;
    }
    else ADCcount++;

    //return;
}