QN908x: getting simple 16bit ADC result

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

QN908x: getting simple 16bit ADC result

Jump to solution
1,082 Views
arpad_toth
Contributor II

How to format the ADC result value to a simple unsigned 16bit preferably without float operation on QN908x?

Datasheet says:

The ADC result is 23-bit signed fractional data, with the MSB (bit 22) as the sign, while the output data to MCU is 32-bit.

ADC_OUTPUT[31:9]: ADC_DATA[22:0]

ADC_OUTPUT[8:0]: 0x00

I'm interested in 0-65535 range.

  rawADCval = ADC_GetConversionResult(ADC);

Tags (1)
0 Kudos
1 Solution
741 Views
FelipeGarcia
NXP Employee
NXP Employee

Hi Arpad,

Sorry for the late reply.

If you want to have only positive numbers please check the configuration below:

static void ADC_Configuration(void)
{
    adc_config_t adcConfigStruct;
    adc_sd_config_t adcSdConfigStruct;

    /**
     * Initial ADC to default configuration.
     */
    ADC_GetDefaultConfig(&adcConfigStruct);
    adcConfigStruct.channelEnable = (1U << DEMO_ADC_CHANNEL);
    adcConfigStruct.channelConfig = (DEMO_ADC_CFG_IDX << DEMO_ADC_CHANNEL);
    adcConfigStruct.triggerSource = DEMO_ADC_TRIGGER;
    adcConfigStruct.convMode = kADC_ConvModeSingle;
    adcConfigStruct.dataFormat = kADC_DataFormat0WithoutIdx;
    adcConfigStruct.refSource = kADC_RefSourceExtWithoutDriver;
    ADC_Init(DEMO_ADC_BASE, &adcConfigStruct);

    /* Initial ADC Sigma Delta(SD) configuration */
    ADC_GetSdDefaultConfig(&adcSdConfigStruct);
    adcSdConfigStruct.vinnSelect = kADC_VinnSelectAvss;
    adcSdConfigStruct.refGain = kADC_RefGain1;

    ADC_SetSdConfig(DEMO_ADC_BASE, DEMO_ADC_CFG_IDX, &adcSdConfigStruct);

    /* Bandgap voltage */
    g_AdcBandgap = ADC_GetBandgapCalibrationResult(DEMO_ADC_BASE, DEMO_ADC_CFG_IDX);

    /* Calibration VINN value */
    g_AdcVinn = ADC_GetVinnCalibrationResult(DEMO_ADC_BASE, &adcConfigStruct);

    /* Enable ADC */
    ADC_Enable(DEMO_ADC_BASE, true);
}

Here I'm using a 1.5V external reference source and I am able to get values from 0 to 3232767 by shifting result_16bits = (g_AdcConvResult >> 16); 

Hope this helps!


Have a great day,
Felipe

View solution in original post

0 Kudos
5 Replies
741 Views
FelipeGarcia
NXP Employee
NXP Employee

Hi Arpad,

As you mentioned it's not possible to change the format in the ADC. The user manual gives you the following formats:

pastedImage_1.png

However, if you check the user guide in chapter 30.2 it says the ADC is a 16-bit sigma-delta ADC.

Which means the ADC resolution is already 16 bits.

QN908x user manual

Best regards,

Felipe.

0 Kudos
741 Views
arpad_toth
Contributor II

Hi Felipe,

I doesn't work

 adcConfigStruct.dataFormat = kADC_DataFormat0WithoutIdx;

s16 result = ADC_GetConversionResult(ADC) >> 16u

gives -63..116 range for GND..3V input, so I loose too much resolution.

and it's not even linear  1.6V gives 310.

Please provide an unsigned float free example how to use the ADC.

Thank you,

0 Kudos
742 Views
FelipeGarcia
NXP Employee
NXP Employee

Hi Arpad,

Sorry for the late reply.

If you want to have only positive numbers please check the configuration below:

static void ADC_Configuration(void)
{
    adc_config_t adcConfigStruct;
    adc_sd_config_t adcSdConfigStruct;

    /**
     * Initial ADC to default configuration.
     */
    ADC_GetDefaultConfig(&adcConfigStruct);
    adcConfigStruct.channelEnable = (1U << DEMO_ADC_CHANNEL);
    adcConfigStruct.channelConfig = (DEMO_ADC_CFG_IDX << DEMO_ADC_CHANNEL);
    adcConfigStruct.triggerSource = DEMO_ADC_TRIGGER;
    adcConfigStruct.convMode = kADC_ConvModeSingle;
    adcConfigStruct.dataFormat = kADC_DataFormat0WithoutIdx;
    adcConfigStruct.refSource = kADC_RefSourceExtWithoutDriver;
    ADC_Init(DEMO_ADC_BASE, &adcConfigStruct);

    /* Initial ADC Sigma Delta(SD) configuration */
    ADC_GetSdDefaultConfig(&adcSdConfigStruct);
    adcSdConfigStruct.vinnSelect = kADC_VinnSelectAvss;
    adcSdConfigStruct.refGain = kADC_RefGain1;

    ADC_SetSdConfig(DEMO_ADC_BASE, DEMO_ADC_CFG_IDX, &adcSdConfigStruct);

    /* Bandgap voltage */
    g_AdcBandgap = ADC_GetBandgapCalibrationResult(DEMO_ADC_BASE, DEMO_ADC_CFG_IDX);

    /* Calibration VINN value */
    g_AdcVinn = ADC_GetVinnCalibrationResult(DEMO_ADC_BASE, &adcConfigStruct);

    /* Enable ADC */
    ADC_Enable(DEMO_ADC_BASE, true);
}

Here I'm using a 1.5V external reference source and I am able to get values from 0 to 3232767 by shifting result_16bits = (g_AdcConvResult >> 16); 

Hope this helps!


Have a great day,
Felipe

0 Kudos
741 Views
arpad_toth
Contributor II

Hi Felipe,

Yes it is a 16bit ADC, but the output is represented as 23-bit signed fractional data, so for 0V input I would get weird big signed numbers 0x123456.

Do you have an example C code how to convert it back to unsigned 16bit?

Thanks,

Arpad

0 Kudos
741 Views
FelipeGarcia
NXP Employee
NXP Employee

Hi Arpad,

 

Unfortunately you cannot get a 16 bits unsigned value cause this ADC is a differential sigma-delta ADC. This means that for single-ended usage, the analog input is connected to the positive end, while the negative end input is connected to an internal generated voltage, VINN.

pastedImage_1.png

However, you can approximate to that behavior if you shift the g_AdcConvResult register as follows:

result_16bits = (g_AdcConvResult >> 16); 

By doing this you will be able to get a value from -32768 to 32767.

Finally, you should change the VINN value to 0 if you want only positive numbers. This is possible if you configure the ADC as follows:

pastedImage_5.png

Best regards,

Felipe.

0 Kudos