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.

F28235 ADC Mirror Result Register problem

Other Parts Discussed in Thread: TMS320F28235

I encountered a problem with ADCRESULT registers on C2000 TMS320F28235.

When I use AdcRegs.ADCRESULTx, there is no problem, just requiring >>4 bits to get the correct value.
When I tried using AdcMirror.ADCRESULTx, the result was not what I expected.

For example, I did ADC conversion from ch0 to ch15, using sequence mode, 8 samples for each channel per sequence.

The result looks like,
(ch00)1514, 1515, 1515, 1516, 1515, 1515, 1514, 1514
(ch01)2585, 2585, 2584, 2584, 2584, 2584, 2584, 2585
(ch02)10, 12, 13, 14, 14, 14, 14, 14
(ch03)12, 14, 14, 15, 15, 15, 16, 15
(ch04)14, 15, 17, 17, 17, 19, 17, 18
(ch05)14, 15, 16, 17, 18, 18, 17, 18
(ch06)12, 14, 16, 16, 16, 16, 17, 17
(ch07)1486, 1487, 1487, 1488, 1487, 1488, 1487, 1487
(ch08)0, 16, 17, 17, 17, 17, 17, 17
(ch09)15, 561, 561, 561, 560, 561, 561, 561
(ch10)561, 14, 15, 15, 15, 16, 15, 15
(ch11)16, 14, 15, 15, 16, 16, 15, 15
(ch12)15, 15, 16, 15, 15, 16, 15, 15
(ch13)15, 14, 15, 16, 15, 16, 15, 15
(ch14)15, 14, 15, 15, 15, 16, 15, 15
(ch15)14, 15, 15, 15, 16, 15, 15, 14

ch08 is connected to DC supply (0V output), ch09 is connected with an amp circuit, ch10 is connected to GND.

The first ADC result of ch09 and ch10 was not correct. I tried many times and reset the board, the problem was still there.

Another example is like,
(ch08)14, 15, 16, 16, 16, 17, 17, 18
(ch09)15, 2344, 2344, 2345, 2344, 2343, 2344, 2344
(ch10)2345, 15, 15, 15, 15, 15, 15, 15

The problem only occurred on ch09 and ch10, sequence mode.

Using AdcRegs.ADCRESULTx has no problem.
Using Cascaded mode has no problem.

Unfortunately, now the problem disappeared! I am not able to reproduce the problem now.
Though I can use AdcRegs.ADCRESULTx instead of the mirror ones, I want to know the root cause.
Any replies appreciated.


Piece of my code.

(All ADC registers are using default values, ADC_cal() is called after reset.)

(CLKIN=25MHz, HSPCLK=CLKIN, ADCCLK=HSPCLK.)



Uint16 DSP_Adc_Seq(Uint16 channel, Uint16 nConv, Uint16* resbuf)
{
Uint16 i, adval, adsum;
volatile Uint16* pAdcResult;
Uint16 SeqId;

if (channel < 8)
SeqId = 0;
else
SeqId = 1;

pAdcResult = &AdcMirror.ADCRESULT0;
//pAdcResult = &AdcRegs.ADCRESULT0;
if (SeqId > 0)
pAdcResult += 8;

nConv = 8;

if (SeqId==0) //Seq1...
{
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = nConv - 1;

AdcRegs.ADCCHSELSEQ1.bit.CONV00 = channel; //
if (nConv > 1)
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = channel;
if (nConv > 2)
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = channel;
if (nConv > 3)
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = channel;
if (nConv > 4)
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = channel;
if (nConv > 5)
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = channel;
if (nConv > 6)
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = channel;
if (nConv > 7)
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = channel;

if (nConv > 8)
AdcRegs.ADCCHSELSEQ3.bit.CONV08 = channel;
if (nConv > 9)
AdcRegs.ADCCHSELSEQ3.bit.CONV09 = channel;
if (nConv > 10)
AdcRegs.ADCCHSELSEQ3.bit.CONV10 = channel;
if (nConv > 11)
AdcRegs.ADCCHSELSEQ3.bit.CONV11 = channel;
if (nConv > 12)
AdcRegs.ADCCHSELSEQ4.bit.CONV12 = channel;
if (nConv > 13)
AdcRegs.ADCCHSELSEQ4.bit.CONV13 = channel;
if (nConv > 14)
AdcRegs.ADCCHSELSEQ4.bit.CONV14 = channel;
if (nConv > 15)
AdcRegs.ADCCHSELSEQ4.bit.CONV15 = channel;
}
else //Seq2...
{
AdcRegs.ADCTRL2.bit.RST_SEQ2 = 1;
AdcRegs.ADCMAXCONV.bit.MAX_CONV2 = nConv - 1;

AdcRegs.ADCCHSELSEQ3.bit.CONV08 = channel;
if (nConv > 1)
AdcRegs.ADCCHSELSEQ3.bit.CONV09 = channel;
if (nConv > 2)
AdcRegs.ADCCHSELSEQ3.bit.CONV10 = channel;
if (nConv > 3)
AdcRegs.ADCCHSELSEQ3.bit.CONV11 = channel;
if (nConv > 4)
AdcRegs.ADCCHSELSEQ4.bit.CONV12 = channel;
if (nConv > 5)
AdcRegs.ADCCHSELSEQ4.bit.CONV13 = channel;
if (nConv > 6)
AdcRegs.ADCCHSELSEQ4.bit.CONV14 = channel;
if (nConv > 7)
AdcRegs.ADCCHSELSEQ4.bit.CONV15 = channel;
}

// Start SEQ1/SEQ2
if (SeqId==0)
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1;// Enable SOCA from SW to start SEQ1
else
AdcRegs.ADCTRL2.bit.SOC_SEQ2 = 1;// Enable SOCB from SW to start SEQ2

// Wait ADC conv completion.
while (1)
{
if (SeqId==0)
{
if ( !AdcRegs.ADCST.bit.SEQ1_BSY )
break;
}
else
{
if ( !AdcRegs.ADCST.bit.SEQ2_BSY )
break;
}
}

adsum = 0;
for(i=1; i<nConv; i++)
{
adval = pAdcResult[i];
if (resbuf)
resbuf[i] = adval; // Copy adc results to buffer
adsum += adval;
}
adval = adsum / nConv;

if (SeqId==0)
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
else
AdcRegs.ADCST.bit.INT_SEQ2_CLR = 1;


return adval;
}

 

  • Hi KAIXIN,

    I haven't thoroughly inspected your code, but my guess is this:

    ADC result registers I think have something like 2 wait states (at least not 0), while ADC mirror registers are 0-wait state.  Because of this, when you read the result registers, the code takes longer and you don't end up reading a register before the conversion results are done.  When you use the mirrors, the reads happen faster and you are able to read the conversion results before they are actually available.

    Is this possible?  There shouldn't be other differences between the registers other than the left/right alignment.

      

  •   Thank you Devin.

    The code is polling AdcRegs.ADCST.bit.SEQ2_BSY flag, until it is cleared.

    I also tried reading AdcMirror.ADCRESULT0 twice and the result was correct.

    This problem may involves another ADC timing problem.

     I measured the ADC conversion time,  dual seq mode, 8 samples on one channel per seq, from setting 

      AdcRegs.ADCTRL2.bit.SOC_SEQx = 1; 

    to  AdcRegs.ADCST.bit.SEQx_BSY is cleared.   (x = 1 or 2).

     

    For seq1(ch=1),  this time is around 2.2us,

    seq2(ch=8), this time is around 1us.

    The problem is that why conversion time is different between seq1 and seq2?

     

    Does this timing difference will cause the mirror results problem.

    When I set cascaded mode, both time is 2.3 us.

    I opened another thread for this problem,

    http://e2e.ti.com/support/microcontrollers/c2000/f/171/t/272649.aspx

     

     

     

     

     

     

     

     

     

  •  

     Hello Devin,

     The problem was solved.  The INT_SEQ1 flag should be used to determine the completion status instead of the SEQ1_BSY flag.

     SEQ1_BSY usually is cleared before INT_SEQ1 flag is set. 

     The consequent question is what  the SEQ1_BSY flag means.  This flag is not explained clearly in user's manual.  In what cases this flag is meaningful? 

     Thank you.