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.

CC2652R: ADC measurement offset

Part Number: CC2652R


Hi

I am working with the CC2652R1 chip for a Thread application and also measuring some sensor data over the ADC channels.

My ADC is referenced to VDDS (ideally 3V), and my input range is 0-VDDS (sensor referenced to VDDS). What I see is an offset of about 60 - 63 on my raw ADC data, e.g. when I am supposed to see a raw value of 2048 (when VDDS/2, using voltage divider between VDDS - GND), I see about 1985 instead.

I would have thought maybe its due to the resistor tolerance, but its not, the offset (-63) is still there even after swapping the resistors in the voltage divider. Also on a separate test I have used sinusoid (0 - 3V) and took the average of the data that showed 1985 - 1988 as well.

I have seen this offset even after using TI’s ADC offset compensation driver in my software. Currently I am hoping for a fix from the TI support teams on this. It might also be really helpful if anyone of you has experienced it already or might even have a solution please let me know.

Regards,
Dhruba

  • You are referring to the values you are getting as raw values.You write "I have seen this offset even after using TI’s ADC offset compensation driver in my software.", what is the result of this operation and please post the code you used to get this result. 

  • Any update?

  • Thanks for your message Guru, since its a company proprietary code I would not be able to send it in open forums, we have sent the code internally to Chris Lande <chris.lande@ti.com>

  • You can also send me a friend request, this way you will be able to send me information that you don't want on a open forum.

    I also need to know what the result of the offset compensation done in your code. Also, have you tried the adcsinglechannel example unmodified to see if you get the expected result then? If you do, what is the difference between the example code and your code?

  • I haven't heard anything from you or Chris, does that mean you have solved the issue? 

  • No I haven't heard from Chris as well. I have sent you a request so that we can share details.

  • I have accepted the friend request.

  • I've sent you some details.

  • I had to dig some in the driver and I believe that I found a bug/ undocumented "feature".

    The following function is called to do offset/ gain correction and to give out a value in uV:

    uint32_t ADCCC26XX_convertToMicroVolts(ADC_Handle handle, uint16_t adcValue){
    ADCCC26XX_HWAttrs const *hwAttrs;
    uint32_t adjustedValue;
    
    DebugP_assert(handle);
    
    /* Get the pointer to the hwAttrs */
    hwAttrs = handle->hwAttrs;
    
    /* Only apply trim if specified*/
    if (hwAttrs->returnAdjustedVal) {
    adjustedValue = adcValue;
    }
    else {
    uint32_t gain = AUXADCGetAdjustmentGain(hwAttrs->refSource);
    uint32_t offset = AUXADCGetAdjustmentOffset(hwAttrs->refSource);
    adjustedValue = AUXADCAdjustValueForGainAndOffset(adcValue, gain, offset);
    }
    
    return AUXADCValueToMicrovolts((hwAttrs->inputScalingEnabled ? AUXADC_FIXED_REF_VOLTAGE_NORMAL : AUXADC_FIXED_REF_VOLTAGE_UNSCALED), adjustedValue);
    }

    If you look at the definition of the driverlib function AUXADCValueToMicrovolts this looks like:

    int32_t
    AUXADCValueToMicrovolts(int32_t fixedRefVoltage, int32_t adcValue)
    {
    // Chop off 4 bits during calculations to avoid 32-bit overflow
    fixedRefVoltage >>= 4;
    return (((adcValue * fixedRefVoltage) + 2047) / 4095) << 4;
    }

    meaning that the first argument should be the (scaled) reference voltage. In your case the VDDS level should be passed instead of AUXADC_FIXED_REF_VOLTAGE_NORMAL . I made a local copy of this function where I pass 3.3 V (testing on launchpad) and then I get close to correct result, I didn't measure the exact VDDS voltage used on the board. 

  • Thanks TER, let us investigate on this for a while, will let you know if the fix works.

  • That is indeed a bug. However, our problem is actually on the raw counts. When we use the ADC_convert function which returns the value in counts we are seeing an offset.

  • Lucas, do you work together with Dhruba or do you have a separate issue? If the later, please post a separate thread since I don't have the overview of how you are setting up your test. 

  • Hi. I work with Dhruba.

    You indeed found a bug on your driver. However, our problem with the offset is not when using the convertToMicroVolts function but rather the one that gives us the raw counts value.

    In any case, to fix the convertToMicroVolts bug, how one can get the VDDS value? Currently it is using a #defined with the 4.3V as you showed.

  • If you mean a offset on the result you get from calling ADC_convert(), yes, that will be the case. The function AUXADCAdjustValueForGainAndOffset() has to be called to compensate the known offset.

    What is the main reason for using VDDS as reference? If you have a system with regulated VDDS you can use the regulated voltage as input to the function but the regulated voltage will have a given inaccuracy that you have to take into account.