CC1312PSIP: Sensor Controller's ADC Deviation.

Part Number: CC1312PSIP
Other Parts Discussed in Thread: LP-XDS110ET, , CC1312R

Tool/software:

Hello

Please be so kind to refer to the description and question below:

Setup:

A proprietary board with CC1312PSIP. The code utilizes Sensor Controller ADC to sample an analog input.

The ADC's reference is VVDS and it is operated in synchronous fashion with scaling turned on and a manual trigger. 

We also use AUXADCAdjustValueForGainAndOffset() on the retrieved ADC result to increase the result's accuracy

The issue at hand: 

We keep seeing deviations in ADC value with the ADC's result being ~20mV to ~50mV lower than expected.   

The deviations seem to increase as a function of the input voltage's magnitude (with 3.3V being the maximum).

E.g. in the current test setup and in conditions where we expect to get 3.3V (0xFFF) - we get 3.287V (0xFEE)...

Questions:

1) Should there be a settling time from the moment the ADC is enabled, triggered and read? 

    1.1) If yes - what is the recommended delay and how should it be distributed between enabling, triggering and reading? 

2) The ADC can receive either a relative reference voltage (VDDS) or a fixed reference. When using a relative reference - how does the ADC retrieve the voltage?

    2.1) Is the ADC reference inlet simply being routed to connect to VDDS thereby receiving an analog value or

            Is the reference a value kept is a register that is being read by the ADC while VDDS sampling is performed by other mechanism in the chip.

    2.2) If the latter in (2.1 is the correct operation description - is VDDS sampled voltage kept in register BAT @ AON_BATMON Registers, offset 0x28? 

        2.2.1) What is the reference used to sample VDDS in BAT register? 

        2.2.2) Does the returned value of function AONBatMonBatteryVoltageGet() give accurate representation of the VDDS value used by the Sensor Controller's ADC?

Thank you so much 

/Gil 

 

  • Hi Gil,

    I will try to find some data on this, let me come back to you today.

    Regards,

    Arthur

  • Hi Gil,

    From the datasheet:

    The variations you are seeing do not seem to match with that plot. Have you enabled input scaling? :

    Overall, I would recommend you to look at the reference implementation, in ADCCC26XX.c:ADCCC26XX_convert, which will answer your questions I hope.

    Regards,

    Arthur

  • Hello Arthur

    Thank you for your reply

    Yes. Input scaling is turned on. 

    I do apologies...but I did not fully understand your suggestion....

    The code we are currently implementing is in the Sensor Controller and it follows the as example given by TI (in the "CC26xx, CC13xx Sensor Controller Studio Getting Started Guide" document). 

    Functions relating to the Sensor controller's ADC did not include your recommendation to the best of my knowledge. 

    Does ADCCC26XX_convert relate to the "main CPU" ? 

    if ADCCC26XX_convert is traced back to the sensor controller, could you email a link to the implementation ?

    Thank you 

    /Gil 

  • Hi Gil,

    My mistake, I indeed picked the wrong CPU. I will keep looking for more useful information.

    Regards,

    Arthur

  • No worries Slight smile

    Maybe we should consider sampling for a longer time (?) 

    Currently sampling before converting takes 42.6usec. 

    Best regards

    /Gil 

  • Hello  (catchy name ;) )

    The suggestion in your thread refers to the compensation procedure applied to raw ADC data incoming to the "main cpu".

    We use this methodology in our design as well. 

    Trouble is that the deviation seen is exhibited despite applying the compensation.

    It should also be notes that in a series of experiments done today i tries to increase the voltage pulse width prior to enabling the ADC.

    I also tries increasing the ADC sample before convert time in function adcEnableSync() all to no avail. The deviation persists despite the increased voltage pulse, sample before convert times and compensation methodology.

    Best regards

    /Gil 

  • The sensor controller return the "raw" value and need the same compensation as done in the ADC driver. Please make sure that you do exactly the same steps. I have seen a fair number of post with similar question (the value deviate from expected) and most of them seem to be caused by FW. To check, use the ADC driver (using the M4) and see if you get the same result.

    What do you use as input for these measurements (power supply, voltage divider...) and how do you know that your result is some mV too low? 

  • Let's do an experiment....

    Setup

    ~~~~~

    LP-EM-CC1312PSIP LaunchPad connected to LP-XDS110ET (the smaller portion) which will serve as the platform for the test.

    The LP-EM-CC1312PSIP portion shall be powered by a 3V CRA123 battery in order to ensure minimal voltage ripple.   

    That same supply voltage shall also be fed as the ADC analog inlet @ DIO25. 

       

    The setup shall run a code through Sensor Controller Studio that will repeatedly sample DIO25 (every second):

    macro sampleAuxInput() {

    S16 adcValue;

    // ADC Assign the AUX Analog Input

    adcSelectGpioInput(AUXIO_A_ADC_IN);

    // Enable the ADC with VDDS RELATIVE REFERNCE & MANUAL Triggering

    adcEnableSync(ADC_REF_VDDS_REL, ADC_SAMPLE_TIME_42P6_US, ADC_TRIGGER_MANUAL); // Changed REF to RELATIVE

    // Trigger the ADC Sampling

    adcGenManualTrigger();

    // Read the ADC Value

    adcReadFifo(adcValue);

    // Disable the ADC

    adcDisable();

    // Copy the ADC Value to the output buffer

    state.adcValue = adcValue;

    }

    //---------------------------------------------------------------------------------------------------------------------------

    sampleAuxInput();

    evhSetupTimer1Trigger(0, 1000, 2);

    Reference

    ~~~~~~~~

    Now, let's use task testing to see ADC results through state.adcValue.

    If my understanding is correct, since we are supplying the ADC inlet with the same voltage as the 3.3V supply rail - I would expect to get an all F's result from the ADC or very close to that. However, the result differs. Instead of getting a result close to 4096 we get a result around 3980 (setting aside the fluctuations)

     

    Testing with our HW

    ~~~~~~~~~~~~~~~~

    Now, let's return to the original hardware and run the full test code via IAR. 

    I shall take 10 raw ADC measurements and make calculation to show the compensated voltage:

    # ADC Raw
    1 3989
    2 3989
    3 3986
    4 3991
    5 3990
    6 3990
    7 3990
    8 3991
    9 3992
    10 3991
    Average  3989.9 -> let's tale 3990…
    For my device 
    gain: 33233
    Offset:  -3
    Compensated value  = (((adcValue + offset) * gain) + 16384) / 32768;  (Taken from CC26xx Driver Library)
    Compensated value  = (((3990-3)* 33233)+ 16384) / 32768 = 4044
    V(ADC_compensated) = 4044/4096*3.058 = 3.019V -> There is a 39mV deviation

     As can be seen, raw ADC results with the original HW seem to be close to that seen with the reference.

    Nevertheless, and despite using the compensation - a deviation exists.

    This deviation currently creates a problem with our application.

    Is this the expected deviation for Sensor Controller ADC? 

    Best regards

    /Gil  

  • If I don't remember wrong, the AUXADCValueToMicrovolts function do a third adjustment of the result (I believe the last line in the function, I don't have CCS installed on this PC so I'm not able to easy step through the code). Check the last line in the function. And do you get the correct results if you use this function on your above experiment? 

  • Here is an excerpt from an older thread (CCS/CC1312R: How to convert the sensor controller adc value to voltage?):

    If you look at the adcsinglechannel example, this uses the function ADC_convertRawToMicroVolts to convert the value.

    This function looks like this:

    /*
     *  ======== ADCCC26XX_convertToMicroVolts ========
     */
    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);
    }"

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Assuming it is the same function for CC1312PSI, convertToMicroVolts() calls the gain and offset correction function after retrieving the preprogrammed chip values
    However - This is the exact same procedure we undertake in our code and yet a deviation exists.

    In should be noted that gain and offset for CC1312PSIP reside in register FCFG1
    Since we are using VDDS as reference (relative reference) the values to be taken from FCFG1 are:
    SOC_ADC_REL_GAIN for gain.

    But for offset - it would seem that the only value supplied is for absolute reference...
    What offset value is used if the reference is relative (the same one)?
    To say that in other words - AUXADCAdjustValueForGainAndOffset() is not restricted to absolute reference. But if that is the case, what is the offset being used when the reference is relative?

    Could that account for the deviation seen?

  • Hello 

    The problem was solved.

    As it turns out, the functions that return gain and offset corrections (AUXADCGetAdjustmentGain(), AUXADCGetAdjustmentOffset())
    were set to return parameters associated with fixed reference voltage rather than a relative reference voltage.

    Once fixed and after applying compensation through AUXADCAdjustValueForGainAndOffset() - results were accurate as expected. 
    Hence a human error....we live - we learn. 

     - Thank you for your comments and suggestions 

    Arthur - thank you so much for your invaluable help