Commit cac7b00f authored by John Brooks's avatar John Brooks Committed by Ben Hutchings

iio: dht11: Use usleep_range instead of msleep for start signal

commit 5c113b5e upstream.

The DHT22 (AM2302) datasheet specifies that the LOW start pulse should not
exceed 20ms. However, observations with an oscilloscope of an RPi Model 2B
(rev 1.1) communicating with a DHT22 sensor showed that the driver was
consistently sending start pulses longer than 20ms:

Kernel 4.7.10-v7+ (n=132):
    Minimum pulse length: 20.20ms
    Maximum:              29.84ms
    Mean:                 24.96ms
    StDev:                2.82ms
    Sensor response rate: 100%
    Read success rate:    76%

On kernel 4.8, the start pulse was so long that the sensor would not even
respond 97% of the time:

Kernel 4.8.16-v7+ (n=100):
    Minimum pulse length: 30.4ms
    Maximum:              74.4ms
    Mean:                 39.3ms
    StDev:                10.2ms
    Sensor response rate: 3%
    Read success rate:    3%

The driver would return ETIMEDOUT and write log messages like this:

[   51.430987] dht11 dht11@0: Only 1 signal edges detected
[   66.311019] dht11 dht11@0: Only 0 signal edges detected

Replacing msleep(18) with usleep_range(18000, 20000) made the pulse length
sane again and restored responsiveness:

Kernel 4.8.16-v7+ with usleep_range (n=123):
    Minimum pulse length: 18.16ms
    Maximum:              20.20ms
    Mean:                 19.85ms
    StDev:                0.51ms
    Sensor response rate: 100%
    Read success rate:    84%
Signed-off-by: default avatarJohn Brooks <john@fastquake.com>
Reviewed-by: default avatarHarald Geyer <harald@ccbib.org>
Signed-off-by: default avatarJonathan Cameron <jic23@kernel.org>
[bwh: Backported to 3.16: adjust context]
Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
parent 15a1b0cb
...@@ -44,7 +44,8 @@ ...@@ -44,7 +44,8 @@
#define DHT11_EDGES_PER_READ (2*DHT11_BITS_PER_READ + DHT11_EDGES_PREAMBLE + 1) #define DHT11_EDGES_PER_READ (2*DHT11_BITS_PER_READ + DHT11_EDGES_PREAMBLE + 1)
/* Data transmission timing (nano seconds) */ /* Data transmission timing (nano seconds) */
#define DHT11_START_TRANSMISSION 18 /* ms */ #define DHT11_START_TRANSMISSION_MIN 18000 /* us */
#define DHT11_START_TRANSMISSION_MAX 20000 /* us */
#define DHT11_SENSOR_RESPONSE 80000 #define DHT11_SENSOR_RESPONSE 80000
#define DHT11_START_BIT 50000 #define DHT11_START_BIT 50000
#define DHT11_DATA_BIT_LOW 27000 #define DHT11_DATA_BIT_LOW 27000
...@@ -152,7 +153,8 @@ static int dht11_read_raw(struct iio_dev *iio_dev, ...@@ -152,7 +153,8 @@ static int dht11_read_raw(struct iio_dev *iio_dev,
ret = gpio_direction_output(dht11->gpio, 0); ret = gpio_direction_output(dht11->gpio, 0);
if (ret) if (ret)
goto err; goto err;
msleep(DHT11_START_TRANSMISSION); usleep_range(DHT11_START_TRANSMISSION_MIN,
DHT11_START_TRANSMISSION_MAX);
ret = gpio_direction_input(dht11->gpio); ret = gpio_direction_input(dht11->gpio);
if (ret) if (ret)
goto err; goto err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment