Skip to content

SPI read_passive_target timeout not working correctly #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
BraindeadBZH opened this issue Feb 18, 2019 · 4 comments
Closed

SPI read_passive_target timeout not working correctly #19

BraindeadBZH opened this issue Feb 18, 2019 · 4 comments

Comments

@BraindeadBZH
Copy link

Hi,

When in SPI mode calling read_passive_target with a timeout, a NFC tag is only detect at the very beginning of the poll. This is not the case with i2c which detects tags through all the duration of the timeout.

@tgikal
Copy link
Contributor

tgikal commented Jul 1, 2019

The SPI and I2C interfaces use an entirely different backend. The problem looks like it's occurring in adafruit_pn532/spi.py -> _wait_ready.

I believe it's related to the with self._spi as spi: statement calling the class each iteration of the while loop:

def _wait_ready(self, timeout=1):
    """Poll PN532 if status byte is ready, up to `timeout` seconds"""
    status = bytearray([reverse_bit(_SPI_STATREAD), 0])

    timestamp = time.monotonic()
    while (time.monotonic() - timestamp) < timeout:
        with self._spi as spi:
            time.sleep(0.02)   # required
            spi.write_readinto(status, status) #pylint: disable=no-member
        if reverse_bit(status[1]) == 0x01:  # LSB data is read in MSB
            return True      # Not busy anymore!
        else:
            time.sleep(0.01)  # pause a bit till we ask again
    # We timed out!
    return False

Changing the while loop around a bit seems to have corrected it:

def _wait_ready(self, timeout=1):
    """Poll PN532 if status byte is ready, up to `timeout` seconds"""
    status = bytearray([reverse_bit(_SPI_STATREAD), 0])

    timestamp = time.monotonic()
    with self._spi as spi:
        while (time.monotonic() - timestamp) < timeout:
            time.sleep(0.02)   # required
            spi.write_readinto(status, status) #pylint: disable=no-member
            if reverse_bit(status[1]) == 0x01:  # LSB data is read in MSB
                return True      # Not busy anymore!
            else:
                time.sleep(0.1)  # pause a bit till we ask again
    # We timed out!
    return False

@caternuson
Copy link
Contributor

@BraindeadBZH Please try the 2.0.7 version of the library when it becomes available:
https://github.com/adafruit/Adafruit_CircuitPython_PN532/releases/tag/2.0.7

@BraindeadBZH
Copy link
Author

Thank you for fixing the issue. Unfortunately I don't have access to the hardware to test this at the moment. I will let you know if I have the chance to get back to this.

@caternuson
Copy link
Contributor

OK. Closing for now. We can reopen if you continue to have the same issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants