I found a BUG!

Who woulda thunk it… While developing a driver for the BMP085 barometric pressure sensor, I found a bug in Visual Studio 2010.

I was getting some pretty wild readings from my sensor, it thought I was 3500m above sea level and last time I checked Albury/Wodonga in Australia is only 165m above sea level. I started getting a little excited, ran outside to play in the snow but unfortunately it was like every other day below the snow line.

I started doing some checking, I passed the sensor values from the sensor’s datasheet into my conversion routines and everything meshed nicely, only the occasional LSB error which went away due to rounding later in the conversion and I got all the right numbers back out the other end.

I was a little puzzled by this time so I started stepping through my code to communicate with the sensor checking the returned data, making sure it was being converted from a byte array into the Int16/32/64 values needed elsewhere. No problem there.

Even more puzzled I checked the code that reads the calibration from the sensor, and puts it into memory for use in the conversion routines. Every chip has its own calibration.
It was here I started seeing something odd.

Where this code…


            AC1 = (Int16)(rawData[0] << 8 + rawData[1]);
            AC2 = (Int16)(rawData[2] << 8 + rawData[3]);
            AC3 = (Int16)(rawData[4] << 8 + rawData[5]);
            AC4 = (UInt16)(rawData[6] << 8 + rawData[7]);
            AC5 = (UInt16)(rawData[8] << 8 + rawData[9]);
            AC6 = (UInt16)(rawData[10] << 8 + rawData[11]);
            B1 = (Int16)(rawData[12] << 8 + rawData[13]);
            MB = (Int16)(rawData[16] << 8 + rawData[17]);
            MC = (Int16)(rawData[18] << 8 + rawData[19]);
            MD = (Int16)(rawData[20] << 8 + rawData[21]);

Should have given me these results…


        A1 = 0x2825;
        A2 = 0xfb70;
        A3 = 0xc82e;
        A4 = 0x864e;
        A5 = 0x61ef;
        A6 = 0x6405;
        B1 = 0x157a;
        B2 = 0x003e;
        MB = 0x8000;
        MC = 0xd4bd;
        MD = 0x0980;

I was getting this…


        A1 = 0x2825;
        A2 = 0xfffffb70;
        A3 = 0xffffc82e;
        A4 = 0x864e;
        A5 = 0x61ef;
        A6 = 0x6405;
        B1 = 0x157a;
        B2 = 0x003e;
        MB = 0xffff8000;
        MC = 0xffffd4bd;
        MD = 0x0980;

I tried hard coding my sensor values as constants but Visual Studio complained about the values for A2, A3, MB and MC not being Int32. And every time I try to work with the values, it thinks they are Int32.

Using the same blocks of code, trying projects for Windows and .NET also gives me the same issue.

I submitted the problem to Microsoft and now It’s wait and see.

A few questions: what are the values in the rawData array? Are the calibration numbers supposed to be signed or unsigned?

Yes, they are calibration data.

The raw data array is as follows…


		[0x00000000]	0x28	byte
		[0x00000001]	0x25	byte
		[0x00000002]	0xfb	byte
		[0x00000003]	0x70	byte
		[0x00000004]	0xc8	byte
		[0x00000005]	0x2e	byte
		[0x00000006]	0x86	byte
		[0x00000007]	0x4e	byte
		[0x00000008]	0x61	byte
		[0x00000009]	0xef	byte
		[0x0000000a]	0x64	byte
		[0x0000000b]	0x05	byte
		[0x0000000c]	0x15	byte
		[0x0000000d]	0x7a	byte
		[0x0000000e]	0x00	byte
		[0x0000000f]	0x3e	byte
		[0x00000010]	0x80	byte
		[0x00000011]	0x00	byte
		[0x00000012]	0xd4	byte
		[0x00000013]	0xbd	byte
		[0x00000014]	0x09	byte
		[0x00000015]	0x80	byte

A1, A2, A3, B1, B2, MB, MC, MD are short values (Int16)
A4, A5, A6 are unsigned short values (UInt16)

do you have simple two line code that we can try?

Should have given me these results…

    A1 = 0x2825;
    A2 = 0xfb70;
    A3 = 0xc82e;
    A4 = 0x864e;
    A5 = 0x61ef;
    A6 = 0x6405;
    B1 = 0x157a;
    B2 = 0x003e;
    MB = 0x8000;
    MC = 0xd4bd;
    MD = 0x0980;

I was getting this…

    A1 = 0x2825;
    A2 = 0xfffffb70;
    A3 = 0xffffc82e;
    A4 = 0x864e;
    A5 = 0x61ef;
    A6 = 0x6405;
    B1 = 0x157a;
    B2 = 0x003e;
    MB = 0xffff8000;
    MC = 0xffffd4bd;
    MD = 0x0980;

Im not sure this is a bug, isnt FFFFFB70 just FB70 sign extended to 32 bits. I think you need to be a little careful about mixing signed and unsigned values

The thing being, it should not be being extended to 32 bits at all. which is the bug. an Int16 is a 2-byte value, not a 4 byte value. The promotion to 32bits should not be happening, to the extent that I can’t fix my code till I get a fix, the compiler and debugger see the errant values as 32bit but the Visual Studio sees it as 16bit. and if I try to fix it so the compiler is happy, the IDE spits the dummy and vice-versa.

Microsoft are looking into it at the moment.

@ Heffo. I have just acquired one of these little BMP085 beauties.

I was wondering if you had written a driver for it yet?

Can I ask one thing…

You may be casting a unsigned 16 bit or a signed 16 bit number but youre evaluating a different variable ie… AC1, AC2 etc what are these if they are 32 bit int’s by default that would do it .

If they are Ushort’s visual studio should have complained about uint16 to ushort conversion(even though you and I know its the same variable)