[Gta04-owner] BMP085 driver in Linux 3.12.0 (Issue #487)

Dr. H. Nikolaus Schaller hns at goldelico.com
Fri Nov 8 23:00:07 CET 2013


Hi,
I have seen sometimes wrong values from the BMP085 sensor, but in most times they are ok [1].

It may look like this:

root at gta04:~# while true; do echo $(cat 
/sys/bus/i2c/devices/2-0077/pressure0_input 
/sys/bus/i2c/devices/2-0077/temp0_input); sleep 0.5; done
94294 393
94299 393
94293 393
94292 393
94289 393
94293 642
100710 393
94293 642
100710 642
100707 393
94296 642
100711 393
94292 393
94285 642
100701 393

(92300+eps and 393 are the correct values).

After digging into the driver I found that adding some additional delay between

	wait_for_completion_timeout(&data->done, msecs_to_jiffies(
								BMP085_TEMP_CONVERSION_TIME));

and

	status = regmap_bulk_read(data->regmap, BMP085_CONVERSION_REGISTER_MSB,
				 &tmp, sizeof(tmp));

either by some printk() [this way the way I detected] or e.g. mdelay(5);
makes the driver report always the right temperature and pressure.

I have no idea what is going wrong, but sometimes there was a timeout from
wait_for_completion_timeout() and data->done.done was still "1".

So it looks as if we loose interrupts. Or the wait_for_completion_timeout() does
end before completion and before the timeout specified. Or the previous completion
is not canceled and ends the next one.

I have also checked that

	msecs_to_jiffies(BMP085_TEMP_CONVERSION_TIME)

is rounded up to 1 on our 100 HZ jiffies raster. So there should be a timeout of 10 ms.

The driver works as follows: there are two basic functions to read raw data (for
temperature and pressure). They write a start-of-conversion command to the BMP.
The BMP changes the EOC line from 0 to 1 and this can be connected to a GPIO
which is then initialized to raise an interrupt on a positive edge. The GPIO number
is configutes in our board file.

The interrupt handler uses a struct completion that is tied to the wait_for_completion_timeout().

I.e. after approx. 4 ms (according to the datasheet), EOC should raise the interrupt
and the completion will happen. Or is EOC is not hooked up or we did loose an
interrupt, there should be a delay of 10 ms which would be enough for correct values..

So the code looks perfectly good.

Anyways, it appears that there may be a too short delay and therefore the ADC will
be read too early and report wrong values.

That is the end of my own ideas. Maybe someone has an idea what is going
wrong. Source code is [2].

Ideas?

BR,
Nikolaus


[1]: http://projects.goldelico.com/p/gta04-kernel/issues/487/
[2]: http://git.goldelico.com/?p=gta04-kernel.git;a=blob;f=drivers/misc/bmp085.c;hb=HEAD


More information about the Gta04-owner mailing list