Hello,
I have trouble using the ADC. Apparently it stems from the function InitADC() not powering up the ADC.
Please see the full code of the program that I am using below. The file DSP281x_Adc.c is as provided in the header file collection. The program is supposed to sample ADCINA0 at 1 kHz. The time base is provided by the general purpose timer 1 in event manager A. A pulse sequence is given to pin PWM1 to confirm that the timer works.
Outputting this signal works as expected as long as InitADC() at the beginning of the main code is commented. If it is not, the 1 kHz signal does not appear at the output. Also, after executing InitADC(), I would expect ADCTRL3 to have the value E6 (bandgap, reference and analog circuitry powered up and clock divider set). This is not the case - the register value is 0 (it is 6 when InitADC() is commented, indicating the setting of the clock divider).
In conclusion, executing InitADC does not power up the ADC as it is supposed to do and further prevents the rest of the code from being executed.
Additional observation that I made: With InitADC() included in the code, upon suspending or terminating the program execution, another code tab opens next to main.c titled "0x3ffc00" or "0x2ec9dd" (it varies) and it says in it
No source available for "0x2ec9dd"
Beneath this message is a View Disassembly… button.
It seems that there is something wrong with the initialization of the ADC by InitADC(). I appreciate your suggestions for possible fixes.
Regards,
Adrian
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
program code:
/*
* main.c
*
* get the ADC working
* 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): PWM1 (I/O pin 9, bottom row fifth pin)
*/
#include "DSP281x_Device.h"
#include "DSP281x_Examples.h"
#include "math.h"
void main() {
float d=0.05;
InitSysCtrl();
InitAdc();
//InitPieCtrl();
//InitPieVectTable();
//InitPeripherals();
// configure pins as peripheral (here: timer) outputs (as opposed to general digital I/O)
EALLOW;
GpioMuxRegs.GPAMUX.all=0xFF;
EDIS;
// 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=3; // input clock prescaler, corresponds to factor 1/8
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=18749; // period register = 150MHz/1kHz/8-1 (HISPCP = 1, prescaler [TPS] 1/8)
EvaRegs.T1CMPR=floor(EvaRegs.T1PR*d); // compare register for GP T1
EvaRegs.T1CNT=0; // initialize counter register
// GP timer control register (EVA)
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 GP timer 2 (1 = active L, 2 = active H)
// GP timer compare control register (EVA)
EvaRegs.COMCONA.bit.CENABLE=1; // enable compare
EvaRegs.COMCONA.bit.CLD=0; // reload compare register CMPR at beginning of switching period
EvaRegs.COMCONA.bit.ACTRLD=0; // reload action control register at beginning of switching period
EvaRegs.COMCONA.bit.FCOMPOE=1; // enable full compare outputs
EvaRegs.COMCONA.bit.FCMP1OE=1; // enable full compare 1 outputs (PWM1,2)
EvaRegs.COMCONA.bit.C1TRIPE=0; // disable trip function that can drive output to high Z
// compare action control register (EVA)
EvaRegs.ACTRA.bit.CMP1ACT=1; // polarity of PWM1 (1 = active L, 2 = active H)
// CMPR1 register
EvaRegs.CMPR1=floor(EvaRegs.T1PR*d); // compare register for PWM1
// configure ADC
AdcRegs.ADCTRL1.bit.SUSMOD=1; // upon emulation suspend finish ADC sequence
AdcRegs.ADCTRL1.bit.CPS=0; // 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.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; // event manager A can 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 clock below 25 MHz
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
while(1){
;
}
}
// TI File $Revision: /main/2 $
// Checkin $Date: April 29, 2005 11:11:45 $
//###########################################################################
//
// FILE: DSP281x_Adc.c
//
// TITLE: DSP281x ADC Initialization & Support Functions.
//
//###########################################################################
// $TI Release: DSP281x C/C++ Header Files V1.20 $
// $Release Date: July 27, 2009 $
//###########################################################################
#include "DSP281x_Device.h" // DSP281x Headerfile Include File
#include "DSP281x_Examples.h" // DSP281x Examples Include File
#define ADC_usDELAY 8000L
#define ADC_usDELAY2 20L
//---------------------------------------------------------------------------
// InitAdc:
//---------------------------------------------------------------------------
// This function initializes ADC to a known state.
//
void InitAdc(void)
{
extern void DSP28x_usDelay(Uint32 Count);
// To powerup the ADC the ADCENCLK bit should be set first to enable
// clocks, followed by powering up the bandgap and reference circuitry.
// After a 5ms delay the rest of the ADC can be powered up. After ADC
// powerup, another 20us delay is required before performing the first
// ADC conversion. Please note that for the delay function below to
// operate correctly the CPU_CLOCK_SPEED define statement in the
// DSP28_Examples.h file must contain the correct CPU clock period in
// nanoseconds. For example:
AdcRegs.ADCTRL3.bit.ADCBGRFDN = 0x3; // Power up bandgap/reference circuitry
DELAY_US(ADC_usDELAY); // Delay before powering up rest of ADC
AdcRegs.ADCTRL3.bit.ADCPWDN = 1; // Power up rest of ADC
DELAY_US(ADC_usDELAY2); // Delay after powering up ADC
}
//===========================================================================
// No more.
//===========================================================================