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.

FDC1004: CAPDAC bug?

Part Number: FDC1004

I found a bug yesterday in my code converting from the 24 bit Two's complement fixed point number the FDC1004 pushes over I2C and a float variable in C. I was trying to manually handle sign of a signed type and the result was less than satisfactory.

However. I have fixed that code and raw hex readings now seem to line up with the hex values themselves. There appears to be another problem, only I think this is a hardware bug in the FDC1004.

I have a terminal where I can set the offset/capdac values and am displaying the exponentially smoothed result on an LCD screen. I can also read the latest raw unfiltered/converted values in the terminal via hex interpretation.

Here's the filtered, converted data with an offset of 0, adjusting capdac only while reinitializing. As you can see, the results seem to follow expression offset=3.125pF*capdac, except in the transition from 7 to 8 where the change seems double what's expected.

0

16pF

1 14.721pF
2 11.597pF
3 8.490pF
4 5.348pF
5 2.326pF
6 -0.863pF
7 -3.868pF
8 -9.5pF
9 -12.619pF
10 -15.729pF
11 -16pF

Raw reading @ CAPDAC=7 (0xE10C3800)

0xE1, bit7= 1 (negative), b6:3 is the integer part, which when inverted corresponds to an integer part of -3

Raw reading @ CAPDAC=8 (0xB3FFFB00)

0xB3, but7= 1 (negative) b6:3 is the integer part, which when inverted corresponds to an integer part of -9

Here's actual configuration information with CAPDAC set to 7.


> setcapdac 7
Ok.
> fdcgetu16 0xFE
fdc_1004(0xFE) = 0x5449

> fdcgetu16 0xFF
fdc_1004(0xFF) = 0x1004

> fdcgetu16 0x08
fdc_1004(0x8) = 0x10E0

> fdcgetu16 0x0C
fdc_1004(0xC) = 0x588

> fdcgetu16 0x0D
fdc_1004(0xD) = 0x00

> fdcgetu16 0x11
fdc_1004(0x11) = 0x4000

Then changing the capdac to 8....

> setcapdac 8
Ok.
> fdcgetu16 0xFF
fdc_1004(0xFF) = 0x1004

> fdcgetu16 0xFE
fdc_1004(0xFE) = 0x5449

> fdcgetu16 0x08
fdc_1004(0x8) = 0x1100

> fdcgetu16 0x0C
fdc_1004(0xC) = 0x588

> fdcgetu16 0x0D
fdc_1004(0xD) = 0x00

> fdcgetu16 0x11
fdc_1004(0x11) = 0x4000

> readraw
Result: 0xB3FB9200

Has anyone else seen this? I believe I've done enough due diligence to eliminate the code as the problem.. Registers appear correct to me.

Here's the code that converts to float:

bool fdc1004_readCapacitance(float *measurement)
{
uint16_t temp;
int32_t result = 0;
bool isNegative = false;
float flt;

//Wait for the first measurement to complete.
do
{
if (STATUS_OK != i2c_fdc1004_getu16(FDC_CONF,&temp))
return false;
} while (!(temp & 0x0008));


if (STATUS_OK != i2c_fdc1004_getu16(MEAS1_MSB,&temp))
return false;

result = temp;
result <<= 16;

if (STATUS_OK != i2c_fdc1004_getu16(MEAS1_LSB,&temp))
return false;

result |= temp;

result >>= 8;

//Convert to picofarads
flt = (result / 524288.0f);

*measurement = flt;

return true;
}