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