periph / conn

Go·Hardware·Lean - Interfaces
https://periph.io
Apache License 2.0
65 stars 11 forks source link

Pin state is only read if the pin's Function() method is called #39

Closed oddcitizenape closed 6 months ago

oddcitizenape commented 6 months ago

Describe the bug The actual state of the pin is only read if the pin's Function() method is called beforehand.

To Reproduce Steps to reproduce the behavior:

  1. Short gpio pin to ground
  2. Run program
    
    package main

import ( "fmt" "log"

"periph.io/x/conn/v3/driver/driverreg"
"periph.io/x/conn/v3/gpio/gpioreg"
"periph.io/x/host/v3"

)

func main() { _, err := host.Init() if err != nil { log.Fatal(err) }

if _, err := driverreg.Init(); err != nil {
    log.Fatal(err)
}

p := gpioreg.ByName("GPIO146")
if p == nil {
    log.Fatal("failed to init. pin")
}

fmt.Println(p.Function())
fmt.Println(p.Read())
gpioreg.Unregister("GPIO146")

}

3. Output: 

In/Low Low

4. Remove short circuit and run again
5.  Output:

In/High High

6. Comment out line:

fmt.Println(p.Function())

and repeat
7. The output will alway be:

Low



**Expected behavior**
The condition should correspond to the shorted/unshorted pin

**Platform (please complete the following information):**
 - OS: Debian GNU/Linux 11 (bullseye)
 - Board: Rockpi 4b Plus
maruel commented 6 months ago
if _, err := driverreg.Init(); err != nil {

should be

if _, err := host.Init(); err != nil {

See the example..

maruel commented 6 months ago

Maybe worth reopening to improve the documentation that led you to settle with driverreg. If you can document how you ended up using it, then we can convert this issue in a documentation fix.

maruel commented 6 months ago

Oh wait I just realized you do both. I'm surprised the second call doesn't fail. This is a bug.

maruel commented 6 months ago

The behavior was intentional, I had forgotten about it; https://github.com/periph/conn/blob/main/driver/driverreg/driverreg.go#L57

Can you state on which configuration you are running this? The behavior highly depends on the hardware.

oddcitizenape commented 6 months ago

@maruel thank you for your reply

It took a while to figure it out, but the fact that my test stopped working after a restart (it always remained low) gave me a clue that something was wrong with the access rights. Here's what I did wrong: instead of running a binary as root, I tried to give the go run command enough rights to the /sys/class/gpio directory and the export/unexport therein as well as exported pins. For some reason this worked fine for a while, but only if I called the Pin object's Function() method at least once. Long story short for posterity: compile a binary (go build .) and run it as root instead of changing groups and adjusting access rights.