Comments (11)
Closing & reopening the port after each read is a workaround (see below), but I couldn't find any code called by NewSPI()
that could solve this problem and is not also called from ReadCard()
...
assertNil(port.Close())
port, err = spireg.Open("SPI0.0")
assertNil(err)
conn, err = mfrc522.NewSPI(port, reset, irq)
assertNil(err)
from periph.
Thanks a lot for detailed report! Can you confirm the interrupt line with an oscilloscope? If not, we'll probably need help with debugging this.
from periph.
I too have encountered this issue on a Raspberry Pi 3. Reinitializing the driver (halting & recreating the PortCloser
and Dev
) solve the issue.
from periph.
Thanks a lot for detailed report! Can you confirm the interrupt line with an oscilloscope? If not, we'll probably need help with debugging this.
I am facing the same issue, here's a trace of the IRQ line:
It's reading the UID 3 times then you see the issue trailing off after that, so the IRQ line is falling but I'm unsure if that's before or after the error is seen.
Code
package main
import (
"encoding/hex"
"log"
"time"
"periph.io/x/periph/conn/spi/spireg"
"periph.io/x/periph/experimental/devices/mfrc522"
"periph.io/x/periph/host"
"periph.io/x/periph/host/rpi"
)
func main() {
if _, err := host.Init(); err != nil {
log.Fatal("Failed to init periphio: ", err)
}
p, err := spireg.Open("")
if err != nil {
log.Fatal("Failed to open spireg: ", err)
}
nfc, err := mfrc522.NewSPI(p, rpi.P1_22, rpi.P1_18)
if err != nil {
log.Fatal("Failed to init MFRC522: ", err)
}
defer nfc.Halt()
for {
uid, err := nfc.ReadUID(10 * time.Second)
log.Printf("UID: %s, err: %s", hex.EncodeToString(uid), err)
}
}
Log
alan@brackenpi:~ $ ./mfrc522test
2021/03/06 15:50:00 UID: f76783d97e, err: %!s(<nil>)
2021/03/06 15:50:00 UID: f76783d97e, err: %!s(<nil>)
2021/03/06 15:50:00 UID: f76783d97e, err: %!s(<nil>)
2021/03/06 15:50:00 UID: , err: mfrc522: back data expected 5, actual 1
2021/03/06 15:50:00 UID: , err: mfrc522 lowlevel: IRQ error
2021/03/06 15:50:00 UID: , err: mfrc522 lowlevel: IRQ error
2021/03/06 15:50:00 UID: , err: mfrc522 lowlevel: IRQ error
2021/03/06 15:50:00 UID: , err: mfrc522 lowlevel: IRQ error
2021/03/06 15:50:00 UID: , err: mfrc522 lowlevel: IRQ error
2021/03/06 15:50:00 UID: , err: mfrc522 lowlevel: IRQ error
2021/03/06 15:50:00 UID: , err: mfrc522 lowlevel: IRQ error
2021/03/06 15:50:00 UID: , err: mfrc522 lowlevel: IRQ error
2021/03/06 15:50:01 UID: , err: mfrc522 lowlevel: IRQ error
... etc
Happy do do more debug.
from periph.
This is interesting:
Lines 191 to 192 in 2d212de
from periph.
Yeah that's a separate work item. It's possible that edges are missed. It's fairly rare on RPi but on AllWinner based CPUs it's sadly totally unreliable.
from periph.
I see. Do you think It's the MFRC522 interrupting immediately (even without a tag) and the code reading that as an error somehow, or do you think the interrupt line falling is just an artefact of the repeated read attempts? I suppose we'd need to instrument the code with GPIO's to tell for sure (my scope is only 2-channel).
from periph.
I have no idea, I never used this device myself.
from periph.
When reading a UID once there are always two device interrupts, as seen above. There is only one call to gpio.PinIn.WaitForEdge()
at the start of selectCard
, this means that the next call to WaitForEdge
will return immediately as there has been an edge since the last call. So we either need to prevent the second device interrupt from happening or service the host interrupt appropriately.
The device interrupt selected (above) interrupts when "receiver has detected the end of a valid data stream". We will get many of these during any transaction, and apparently at least one if we try to read with no card present as this condition doesn't clear itself after one failed read. There doesn't appear to be a more fine grained interrupt available, so it looks like we have to pick a sensible point to service the host GPIO interrupt.
I think we can call WaitForEdge(0)
before line 198 in low_level.go: https://github.com/google/periph/blob/master/experimental/devices/mfrc522/commands/low_level.go#L196-L209
This will clear the host GPIO interrupt before we asynchronously call WatForEdge(timeout)
, we don't expect a device interrupt until after ComIrqReg is cleared by line 207. The docstring for this function already says it is waiting for IRQ to "strobe", not for it to have previously "strobed".
In theory we could prevent the second device interrupt by not clearing ComIrqReg in Init()
which is called after WaitForEdge()
in selectCard()
, but doing so prevents any UID being read, I'm not sure why.
I also realise this whole conversation should probably move to this repo? https://github.com/periph/devices
from periph.
Yes, I didn't transfer the issues to the new repos yet. I just realized it's actually fairly easy, it's just a bit tedious as I have to do it for individual issues. Will try on an inactive issue first to confirm it works.
from periph.
Attempting to migrate an issue results in a 500 (!) so let's stick it here for now.
from periph.
Related Issues (20)
- [Question] How do I set a pin to alt0? HOT 6
- All pins are exported during bcm283x Init HOT 3
- Support for firmata HOT 2
- gpio-read: bcm283x-gpio (GPIO7): pull cannot be used when subsystem gpiomem not initialized. HOT 21
- Go get fetches v3.4.0 if using go modules HOT 3
- Support for BME680 HOT 3
- Halt() does not unblock WaitForEdge() HOT 3
- Feature SSD1322 HOT 5
- spi to slow HOT 5
- onewire didnot work HOT 9
- Omega2: declare headers HOT 3
- Experimental serial package doesn't export essential func HOT 7
- Unable to set GPIO pin pull on Raspberry Pi 4 HOT 19
- MFRC522 hang on WaitForEdge HOT 2
- HX711: unstable readings and reading before data is ready HOT 2
- spi: rename MISO/MOSI to COPI/CIPO HOT 2
- I2C documentation not clear on read/write operation HOT 2
- MFRC522 - Problem reading Tag HOT 3
- pmem example code incorrect HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from periph.