Re: [PATCH 1/2] iio: dht11: forked a driver version that polls sensor's signal from GPIO

From: pelzi
Date: Sun Feb 05 2023 - 12:47:15 EST


As it turned out, on my Allwinner H3 based BananaPi M2 Zero, it is
required to explicitly set a low IRQ debounce filter time, as there is
a default debounce filter active that appears to filter something
around 150µs. This causes IRQs from DTH11/22 devices to be filtered
out, evenly over the transmission time.

Reading the datasheet carefully it seems to be documented that a
32kHz clock, scaled by 1, is the default base of an interrupt
debounce filter – taking a simple notice "Default Value 0x00000000"
very verbatim. Depending on the algorithm, this 32µs clock as basis
seems plausible to destroy the expected signal and anyway, so it does.

The device tree overlay quoted below makes the IRQ based driver (in
my falling-edge-only flavour) work like a charm. Tests of reliability,
system load, comparison to the original driver are still ongoing.

Are there any useful next steps arising from this observation? Perhaps
at least some Documentation? I'm even concerned about the default
setting being used by

arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts

As far as I understand, this setting applies to the full IRQ bank,
appearently including GPIOs usable for UARTs including the separate
UART used for debugging (CON3).

OTOH, applying the dt overlay below relaxes a filter and could make
bounces show up in applications that do not currently experience
bouncing artefacts.

Obviously, a polling version of the driver is not required in this case,
I vote to rejecting it.

Cheers

Andreas


// Definitions for dht11 module
/*
Adapted from dht11.dts for Raspberrypi, by Keith Hall
Adapted by pelzi.
*/
/dts-v1/;
/plugin/;

/ {

        fragment@0 {
                target-path = "/";
                __overlay__ {

                        temperature_humidity: dht11@6 {
                                compatible = "dht22", "dht11";
                                pinctrl-names = "default";
                                pinctrl-0 = <&dht11_pins>;
                                gpios = <&pio 0 6 0>; /* PA6 (PIN 7), active high */
                                status = "okay";
                        };

                };
        };

        fragment@1 {
                target = <&pio>;
                __overlay__ {
                        input-debounce = <5 0>; /* 5µs debounce on IRQ bank 0, default on bank 1 */
                        dht11_pins: dht11_pins {
                                pins = "PA6";
                                function = "gpio_in";
                                /*bias-pull-up; not required for 3-pin version of sensor */
                        };
                };
        };

        __overrides__ {
                gpiopin =       <&dht11_pins>,"pins:0",
<&temperature_humidity>,"gpios:8";
        };
};

Am 02.02.23 um 21:53 schrieb Harald Geyer:
Am Mittwoch, dem 01.02.2023 um 13:51 +0100 schrieb
pelzi@xxxxxxxxxxxxxxx:
I understand that the first priority is in finding out if there is
actually a proper
use case for a polling implementation at all. Only then, it might be
worth to extend
the existing dht11 module by an polling alternative.

Am 31.01.23 um 11:18 schrieb harald@xxxxxxxxx:
On 2023-01-30 21:42, Andreas Feldner wrote:
On a BananaPi M2 Zero, the existing, IRQ based dht11 driver is
not
working,
but missing most IRQs.
That's quite surprising as the driver works well on many similar
systems
based on Allwinner SoCs. I suspect the problem is with your setup.
Maybe
some other (polling?) driver is slowing everything down.
Can you give me a hint how to look for signs of such a situation?
The obvious things to try:

Enabling debug output for the dht11 driver, to look into which
interrupts are actually missing: Is it a "block" of interrupts?
Are they randomly distributed? Are they somewhat equally spaced?
This should give some hints about the nature of the problem.

Try to reproduce the problem on a minimal system:
Unload as many modules as possible.
Maybe just use a system on a ram disk.
As little user space programms running as possbile.
You might find OpenWRT helpful.

Try other kernel versions. (Unlikely, but it might be some
completely unrelated regression.)

Implement debugging output in your polling driver to investigate,
why *that* performs so bad. It probably is the same issue.

If this doesn't lead anywhere, then it is a tough problem, so
let's for now assume, you find something.


BTW I took some pride in building the board's system image from
reproduceable sources: Debian kernel package
linux-image-5.10.0-20-armmp-lpae, and the device tree from 

arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts

So the setup should be reproducible, unlike other approaches
advertised
in the BananaPi forum...

What I did is

- check /proc/interrupts. The highest volume interrupts there are two
instances of sunxi-mmc, one generating about 50 interrupts per
second,
the other about 25. Those (and most) interrupts are GICv2, but the
GPIO
releated are sunxi-pio-{level,edge}

- check dmesg: literally no messages apart from dht11_poll itself

- check top: sugov:0 is reported to eat 10% of one cpu, but I
understand
that's expected and an artifact anyway. Changing the scaling governor
to
"performance" eliminates this, but does not help in making the irq
driven dht11 work.

- check vmstat: ir is between 50 and 200 apart from short spikes,
those
probably related to a certain cron job

- check sysstat cpu, mem, threads, mutex: each of the 4 cores has a
low
performance (a factor of 15 lower than a Raspberrypi 3), but
constant,
low stddev, etc. No surprises running e.g. 8 threads instead of 4.

So, apart from the fact that it is missing about 3/4 of the IRQs the
dht11 driver should get, I have no indication that something might be
wrong with the board or its setup. Where else should I look?
There are many possible issues, that are difficult to investigate
directly. E.g. cache poisoning, some code disabling interrupts just
a bit to long etc. Thus the use of minimal systems.

Following the hints in Harald Geyer's comments I
tried to implement a version of the driver that is polling the
GPIO
sensor in a busy loop, not using IRQ altogether.
IIRC one readout takes about 80 milliseconds. That's a very long
time for
a busy loop. I doubt this is acceptable for inclusion in the
kernel. Of
course also Jonathan's comments apply.
Seems to be a bit less, just in case that matters. Given the timing
chart I'd expect

on average: 200µs + 40 * 100µs = 4,2ms

worst case (device trying to send all one-bits): 200µs + 40 * 120µs =
5,0ms

Ack.

Good luck,
Harald