MFRC522 hang on WaitForEdge
System-Glitch opened this issue · 2 comments
Describe the bug
I'm using the MFRC522 example to read data on a Mifare Classic tag without authentication on a Raspberry Pi 4B (Raspbian and SPI enabled). I changed the key to key := [6]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
and the auth method to PICC_AUTHENT1A
.
The program hangs on irqChannel <- r.irqPin.WaitForEdge(timeout)
in LowLevel.WaitForEdge
until timeout, then writing "Didn't receive device data". If I edit the lib's code and change this line to irqChannel <- true
, everything works perfectly.
To Reproduce
Steps to reproduce the behavior:
- Pin layout:
RC522 Pin | Raspberry Pi Pin |
---|---|
3.3V | Pin 1 |
RST | Pin 22 |
GND | Pin 9 |
MISO | Pin 21 |
MOSI | Pin 19 |
IRQ | Pin 18 |
SCK | Pin 23 |
SDA | Pin 24 |
- Run program in debugger
package main
import (
"fmt"
"log"
"time"
"periph.io/x/periph/conn/spi/spireg"
"periph.io/x/periph/experimental/devices/mfrc522"
"periph.io/x/periph/experimental/devices/mfrc522/commands"
"periph.io/x/periph/host"
"periph.io/x/periph/host/rpi"
)
func main() {
// Make sure periph is initialized.
if _, err := host.Init(); err != nil {
log.Fatal(err)
}
// Using SPI as an example. See package ./spi/spireg for more details.
p, err := spireg.Open("")
if err != nil {
log.Fatal(err)
}
fmt.Println(p)
defer p.Close()
rfid, err := mfrc522.NewSPI(p, rpi.P1_22, rpi.P1_18)
if err != nil {
log.Fatal(err)
}
// Idling device on exit.
defer rfid.Halt()
// Setting the antenna signal strength.
rfid.SetAntennaGain(5)
key := [6]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
timedOut := false
cb := make(chan []byte)
timer := time.NewTimer(10 * time.Second)
// Stopping timer, flagging reader thread as timed out
defer func() {
timer.Stop()
timedOut = true
close(cb)
}()
go func() {
log.Printf("Started %s", rfid.String())
for {
// Trying to read data from sector 8 block 0
data, err := rfid.ReadCard(10*time.Second, byte(commands.PICC_AUTHENT1A), 2, 0, key)
// If main thread timed out just exiting.
if timedOut {
return
}
// Some devices tend to send wrong data while RFID chip is already detected
// but still "too far" from a receiver.
// Especially some cheap CN clones which you can find on GearBest, AliExpress, etc.
// This will suppress such errors.
if err != nil {
continue
}
cb <- data
return
}
}()
for {
select {
case <-timer.C:
log.Fatal("Didn't receive device data")
return
case data := <-cb:
log.Println(data)
return
}
}
}
Goroutine should hang at the line mentioned above.
Expected behavior
IRQ WaitForEdge should not time out.
Platform:
- OS: Raspbian 10 buster
- Board Raspberry Pi 4B
I suspect periph/devices@7cccb95 fixed it. Please update to periph.io/x/devices/v3/mfrc522 and file a bug at https://github.com/periph/devices if it still reproduces.