* Jean Delvare <khali at linux-fr.org> [2003-08-12 00:05:44 +0200]: > > Hi all, > > I'm in the process of writing a driver for the LM90 (we have at least > two users waiting for it). I am now facing a problem related to 11-bit > temperatures the LM90 handles for the remote temperature. The 11 bits > are splitted over two different bytes. This means that reading from > these two bytes in sequence could, in a few cases, read the high byte of > a conversion and the low byte of another conversion. This is bad and > unwanted. Other high precision chipsets (the LM75 comes to mind) don't > have the problem because you read a word, so it all happens in a single > operation and the above-mention case can't happen. > > Here's what National Semiconductor say in the datasheet: > > "When retrieving all 10 bits from a previous remote diode temperature > measurement, the master must insure that all 10 bits are from the same > temperature conversion. This may be achieved by using one-shot mode or > by setting the conversion rate and monitoring the busy bit so that no > conversion occurs in between reading the MSB and LSB of the last > temperature conversion." > > To me, both proposed solution are bad. In the first case, you'll have to > wait for the full conversion each time you want to read the value. The > I2C bus is slow enough, the hell if we want to wait even more each time Why not fire off a one-shot conversion and wait for it to finish? 10kHz smbus speed (conservative - spec'ed minimum according to datasheet) 40 bits per read (smbus write + smbus read incl. start/stop/ack bits) 22 registers to read (conservative - probably need only 15) So 31.25ms for the conversion + 88ms for the update => ~120ms. There's other overhead too but it can't be helped. This is pushing the limits of what people can notice, worst case. But if you really must optimize it... update() { start_conversion(); read_non_volatile_regs(); while (still_converting) i2c_delay(1); read_volatile_regs(); } > we read a value. In the second case, I think it just doesn't work > because reading the busy bit isn't different from reading the second > temperature byte. Reading that the busy bit is set doesn't help us. What > will we do? Read the first byte again, then busy again, until the busy > bit isn't set? It is possible that the conversion occurs between us > reading the first byte and us reading the busy flag, so we don't see the > flag and read the second byte, although it doesn't match the fisrt byte. > Or I am missing obvious? > > Is there another driver that has the same kind of probleme, so that I > can take a look at the proposed solution? > > The solution I have come to is: > > Read first byte, read second byte, read first byte again. If the new > first byte matches the old one, it's ok, we have our reading (most > cases). If not, read the second byte once again. If the conversion rate > is low enough (and I'll make sure it is) the second try should not fail. > The good point there is that we don't have to wait for any event nor > monitor any flag. The bad point is a 50 to 100% overhead. Still I > believe it's overall better than the other possibilities (if you can > call them that way). > > Note that if we can't get to a solution everyone is happy with, I'll > plain *drop* support for the extra resolution registers. After all, > what's the point in a 0.125 degree resolution when the sensor has a +/- > 3 degrees accuracy? I just don't get it. Who on earth wants to know it's > CPU temperature with a 0.125 degrees resolution anyway? And it makes the > driver *much* more complicated. Useless precision is a pet peeve of mine, too. I was once asked to extend the std C lib struct tm to include a field for microseconds - as if there was some calculation that cared about months and uS at the same time... equivalent to 12 decimals of precision?! Regards, -- Mark M. Hoffman mhoffman at lightlink.com