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.

ADC2 wrong internal calibration

Hi,

I'm experiencing problem with ADC2 internal calibration.

At initialisation of my program I start the calibration of both ADC, one after the other, and the ADC2 calib value seems always wrong. If I re-execute the calibration few seconds later I get another calibration offset for ADC2..

Here's the code I'm executing at initialization:

void DrvAdc::AdcCalibrate( )
{
   // Enable calibration mode (When this bit is set, the analog input channel multiplexer
   // is disconnected and the calibration reference voltage is connected to
   // the ADC core input)
   regADCPtr->calCR.bit.calEn = 1;

   // Clear HILO
   // Clear bridge enable
   // => Voltage Reference = (ADRefHi*R1 + ADRefLo*R2) / (R1 + R2)
   regADCPtr->calCR.bit.hilo = 0;
   regADCPtr->calCR.bit.bridgeEn = 0;

   // Value used to sum all result.
   uint32_t calSum = 0;
   // Calibration offset error...
   //for( uint16_t acq = 0; acq < 8; acq++ )
   {
      // start calibration conversion (single conversion)
      regADCPtr->calCR.bit.calSt = 1;

      // Wait until calibration is finished
      while( regADCPtr->calCR.bit.calSt != 0 );

      // read back result
      calSum += regADCPtr->calR.bit.adCalR;
   }

   // Calc mid-point calibration
   // Set HILO
   // => Voltage Reference = (ADRefLo*R1 + ADRefHi*R2) / (R1 + R2)
   regADCPtr->calCR.bit.hilo = 1;

   // Calibration offset error...
   //for( uint16_t acq = 0; acq < 8; acq++ )
   {
      // start calibration conversion (single conversion)
      regADCPtr->calCR.bit.calSt = 1;

      // Wait until calibration is finished
      while( regADCPtr->calCR.bit.calSt != 0 );

      // read back result
      calSum += regADCPtr->calR.bit.adCalR;
   }

   // Divide by 2 (1 volt ref + 1 volt ref) to get mid-point
   // We add 0x1 to round up the value. (Ex: For 16 acq, add 8/16(0,5))
   calSum = (calSum + 0x01) >> 1;

   // Calculate the compensate offset and apply it
   regADCPtr->calR.bit.adCalR = (0x800 - calSum);

   // Disable calibration and write back to 0 all other calibration variables
   regADCPtr->calCR.bit.calEn    = 0;
   regADCPtr->calCR.bit.hilo     = 0;
   regADCPtr->calCR.bit.bridgeEn = 0;
   regADCPtr->calCR.bit.calSt    = 0;

}

Here's the register adCalR values

After a power ON:

      ADC1:   adCalR = 4087

      ADC1:   adCalR = 854

If I re-execute the calibration after initialization:

     ADC1:   adCalR = 4087

     ADC1:   adCalR = 1189

Is it normal that both ADC calibration offset values are so different?

Is there a stabilisation time to wait before executing ADC calibration after a power-ON reset?

Thanks

David.

  • David,

    For case 1 (BridgeEn=0, Hilo=0), the ideal result is 7/12*REFHI = 2389

    For case 2 (BridgeEn=0, Hilo=1), the ideal result is 5/12*REFHI = 1706

    Can you please check your ADC init value? Especially the value in ADEVSAMP register ( Event Group Acquisition Time). The sampling time need to be at least 1uS.

    Regards,

    QJ

  • Hi QJ,

    You seem to be right concerning the minimum sampling time of 1us. However, I'm not able to change it in code... What I mean is I write the following code :

      // Setup event group sample window
      regADCPtr->evSamp.bit.evAcq = 28;                // 28 -> 30 adc tick = 30/30MHz = 1us

    After initialization the value of evSamp.all is back to 0.

    Is there an order to respect when modifying  the sampling time register?

    Do you know if the ADCLK needs to be prescaled before or after setting the samplig time register?   (regADCPtr->clockCR.bit.ps = 2;)

    Thanks

    David.

  • QJ,

    I realised that I was setting the groups sampling time instead of the event sampling time. So your 1us sampling time is the solution to my problem.

    Thank you.

    David.