Other Parts Discussed in Thread: CONTROLSUITE
I have a strange error which looks like crosstalk between the ADC and DAC systems in the 28075. The picture below shows my setup. I am monitoring a photodiode amplifier with ADCA input A3 using a single SOC0. I am also (on the ADC B system) monitoring four slowly changing signals at an entirely different time. One of them is a thermistor on input B3. The setup for ADCB uses four sequential SOC's (0,1,2 and 3) and the input channels are B2, B3, 14 and 15.
My setup code for the ADC's and DAC's is:-
(ADC)
void SetupADCSoftware(void)
{Uint16 acqps;
// ADC resolution is the same for both ADC's, so "acqps" value can be used for both.
if(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION) acqps = 14; // 75ns
else acqps = 63; // 320ns
EALLOW; // ADC setup registers are protected
// ADC A, fast detector input - NB PINS A2 AND A3 STRAPPED FOR FAULT IDENTIFICATION
AdcaRegs.ADCSOC0CTL.bit.CHSEL = 3; // SOC0 will convert channel A3 (pin 22 PZP package)
AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; // sample window is acqps + 1 SYSCLK cycles
AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; // end of SOC0 will set INT1 flag
AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; // enable INT1 flag
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // make sure INT1 flag is cleared
// ADC B, thermistor, laser diode x 2, CAN address resistive selection
AdcbRegs.ADCSOC0CTL.bit.CHSEL = 2; // SOC0 will convert pin B2 - CANADR
AdcbRegs.ADCSOC0CTL.bit.ACQPS = acqps;
AdcbRegs.ADCSOC1CTL.bit.CHSEL = 3; // SOC1 will convert pin B3 - THERMISTOR
AdcbRegs.ADCSOC1CTL.bit.ACQPS = acqps;
AdcbRegs.ADCSOC2CTL.bit.CHSEL = 14; // SOC2 will convert pin B14 - LAMON (A) LBMON (B)
AdcbRegs.ADCSOC2CTL.bit.ACQPS = acqps;
AdcbRegs.ADCSOC3CTL.bit.CHSEL = 15; // SOC3 will convert pin B15 - LBMON (B) LAMON (B)
AdcbRegs.ADCSOC3CTL.bit.ACQPS = acqps;
AdcbRegs.ADCINTSEL1N2.bit.INT1E = 1; // enable INT1 flag
AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // make sure INT1 flag is cleared
EDIS;
}
(DAC)
void Configure_DAC(Uint16 dacnum) // param is DACA - DACC
{EALLOW;
DAC_PTR[dacnum]->DACCTL.bit.DACREFSEL = REFERENCE; // internal VRef
DAC_PTR[dacnum]->DACOUTEN.bit.DACOUTEN = 1; // buffer ON
DAC_PTR[dacnum]->DACVALS.all = 0; // clear data register
DELAY_US(10); // Delay for buffered DAC to power up
EDIS;
}
And my driver code for the ADC's is as follows:-
void Aux_ADC(void) // Auxilliary ADC inputs to ADC B
{int CANAdr,THVal, LMON1, LMON2;
DINT; // kill the World
EALLOW;
AdcbRegs.ADCINTSEL1N2.bit.INT1SEL = 3; // select SOC0 - 15, end of SOC3 will set INT1
EDIS;
AdcbRegs.ADCSOCFRC1.all = 0x0F; // bit per SOC, Force Start of SOC0 - SOC3
while (!AdcbRegs.ADCINTFLG.bit.ADCINT1); // Wait for ADCINT1
AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // Clear ADCINT1
CANAdr = AdcbResultRegs.ADCRESULT2; // save the raw data from chan B2
THVal = AdcbResultRegs.ADCRESULT3; // save the raw thermistor data chan B3
LMON1 = AdcbResultRegs.ADCRESULT14; // save the raw monitor data chan 14
LMON2 = AdcbResultRegs.ADCRESULT15; // save the raw monitor data chan 15
EINT; // World back on
if (CANAdr > 3300) CANAdr = 3300; // limit to 3.3 volts
CANVal = CAN_ADR_Read(CANAdr); // decode the CAN address
if (THVal > 3300) THVal = 3300; // limit to ambient at 25 deg
THVal = (3300 - THVal) / 550; // invert and scale for 3.3 volts at 60 deg
Put_DACOutB(THVal); // send to the Peltier controller
if (LMON1 > 3300) LMON1 = 3300; // limit to 3.3 volts - NOT USED YET
if (LMON2 > 3300) LMON2 = 3300; // limit to 3.3 volts - NOT USED YET
}
// ********************* Data and AGC processing ************************************************************
// Getsample - reads in an FFTSIZE-sample to to work0[] (raw) and to buff[] (averaged)
// param ScaleItem is part of the AGC system, matches proccessed Doppler amplitude to the FFT process
// returns the average Doppler value for second (FFT-related) AGC process - smooth by 50 (a guess)
int GetSample(float ScaleItem)
{int p; // local buffer indexing
int readval; // input value after coarse AGC has been applied
int ADCptr = 0; // local data transfer size
int val;
mean_value = 0; // placeholder for running average
accumulator = 0; p = -AvConstant; // start with a clean average
AvMult = (AvConstant - 1) / AvConstant; // moving average multiplier
DINT; // kill the World
EALLOW;
AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; // select SOC0 - 15, end of SOC0 will set INT1 flag
EDIS;
for (ADCptr = p; ADCptr < FFTSIZE; ADCptr++) // read in <AvConstant> values to create the average
{AdcaRegs.ADCSOCFRC1.all = 0x0001; // 1 bit per SOC, Force Start of Conversion bit 0
while (!AdcaRegs.ADCINTFLG.bit.ADCINT1); // Wait for ADCINT1
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // Clear ADCINT1
if (ADCptr >= 0) // now fetch the main body of data
val = AdcaResultRegs.ADCRESULT3; // chan 0 - 15, save the raw data from chan A3
}
EINT;
return val; // exit with last value
}
So here's the puzzle. When I shine a light on the photodiode, the DACB output changes. BUT when I monitor ADCRESULT3 for ADCA, I can't see the photodiode data changing.
I have checked for all of the likely errors (using b registers when I actually meant a).
Have I somehow mixed up my SOC's and channels?
Yours, in desperation,
Chris Moir
