Skip to content

Commit 03c9f11

Browse files
committed
do a hardware reset before I2C, tested with raspi
1 parent 78ababa commit 03c9f11

File tree

2 files changed

+48
-17
lines changed

2 files changed

+48
-17
lines changed

adafruit_pn532.py

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,14 @@
176176
# pylint: enable=bad-whitespace
177177

178178

179+
def _reset(pin):
180+
pin.direction = Direction.OUTPUT
181+
pin.value = True
182+
time.sleep(0.1)
183+
pin.value = False
184+
time.sleep(0.5)
185+
pin.value = True
186+
time.sleep(0.1)
179187

180188
def reverse_bit(num):
181189
"""Turn an LSB byte to an MSB byte, and vice versa. Used for SPI as
@@ -201,13 +209,10 @@ def __init__(self, *, debug=False, reset=None):
201209
"""
202210
self.debug = debug
203211
if reset:
204-
reset.direction = Direction.OUTPUT
205-
reset.value = True
206-
time.sleep(0.1)
207-
reset.value = False
208-
time.sleep(0.5)
209-
reset.value = True
210-
time.sleep(0.1)
212+
if debug:
213+
print("Resetting")
214+
_reset(reset)
215+
211216
try:
212217
self._wakeup()
213218
self.get_firmware_version() # first time often fails, try 2ce
@@ -311,7 +316,11 @@ def call_function(self, command, response_length=0, params=[], timeout=1): # pyl
311316
for i, val in enumerate(params):
312317
data[2+i] = val
313318
# Send frame and wait for response.
314-
self._write_frame(data)
319+
try:
320+
self._write_frame(data)
321+
except OSError:
322+
self._wakeup()
323+
return None
315324
if not self._wait_ready(timeout):
316325
return None
317326
# Verify ACK response and wait to be ready for function response.
@@ -470,27 +479,41 @@ def _write_data(self, framebytes):
470479

471480
class PN532_I2C(PN532):
472481
"""Driver for the PN532 connected over I2C."""
473-
def __init__(self, i2c, *, irq=None, reset=None, debug=False):
482+
def __init__(self, i2c, *, irq=None, reset=None, req=None, debug=False):
474483
"""Create an instance of the PN532 class using I2C. Note that PN532
475484
uses clock stretching. Optional IRQ pin (not used),
476485
reset pin and debugging output.
477486
"""
478487
self.debug = debug
479488
self._irq = irq
489+
self._req = req
490+
if reset:
491+
_reset(reset)
480492
self._i2c = i2c_device.I2CDevice(i2c, _I2C_ADDRESS)
481493
super().__init__(debug=debug, reset=reset)
482494

483495
def _wakeup(self): # pylint: disable=no-self-use
484496
"""Send any special commands/data to wake up PN532"""
497+
if self._req:
498+
self._req.direction = Direction.OUTPUT
499+
self._req.value = True
500+
time.sleep(0.1)
501+
self._req.value = False
502+
time.sleep(0.1)
503+
self._req.value = True
485504
time.sleep(0.5)
486505

487506
def _wait_ready(self, timeout=1):
488507
"""Poll PN532 if status byte is ready, up to `timeout` seconds"""
489508
status = bytearray(1)
490509
timestamp = time.monotonic()
491510
while (time.monotonic() - timestamp) < timeout:
492-
with self._i2c:
493-
self._i2c.readinto(status)
511+
try:
512+
with self._i2c:
513+
self._i2c.readinto(status)
514+
except OSError:
515+
self._wakeup()
516+
continue
494517
if status == b'\x01':
495518
return True # No longer busy
496519
else:

examples/pn532_simpletest.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,28 @@
1010
from digitalio import DigitalInOut
1111
from Adafruit_Circuitpython_PN532 import adafruit_pn532
1212

13-
reset_pin = DigitalInOut(board.D6)
14-
1513
# I2C connection:
1614
i2c = busio.I2C(board.SCL, board.SDA)
17-
pn532 = adafruit_pn532.PN532_I2C(i2c, debug=False, reset=reset_pin)
15+
16+
# Non-hardware
17+
#pn532 = adafruit_pn532.PN532_I2C(i2c, debug=False)
18+
19+
# With I2C, we recommend connecting RSTPD_N (reset) to a digital pin for manual
20+
# harware reset
21+
reset_pin = DigitalInOut(board.D6)
22+
# On Raspberry Pi, you must also connect a pin to P32 "H_Request" for hardware
23+
# wakeup! this means we don't need to do the I2C clock-stretch thing
24+
req_pin = DigitalInOut(board.D12)
25+
pn532 = adafruit_pn532.PN532_I2C(i2c, debug=False, reset=reset_pin, req=req_pin)
1826

1927
# SPI connection:
2028
#spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
2129
#cs_pin = DigitalInOut(board.D5)
22-
#pn532 = adafruit_pn532.PN532_SPI(spi, cs_pin, debug=False, reset=reset_pin)
30+
#pn532 = adafruit_pn532.PN532_SPI(spi, cs_pin, debug=False)
2331

2432
# UART connection
2533
#uart = busio.UART(board.TX, board.RX, baudrate=115200, timeout=100)
26-
#pn532 = adafruit_pn532.PN532_UART(uart, debug=False, reset=reset_pin)
34+
#pn532 = adafruit_pn532.PN532_UART(uart, debug=False)
2735

2836
ic, ver, rev, support = pn532.get_firmware_version()
2937
print('Found PN532 with firmware version: {0}.{1}'.format(ver, rev))
@@ -34,7 +42,7 @@
3442
print('Waiting for RFID/NFC card...')
3543
while True:
3644
# Check if a card is available to read
37-
uid = pn532.read_passive_target(timeout=0.25)
45+
uid = pn532.read_passive_target(timeout=0.5)
3846
print('.', end="", flush=True)
3947
# Try again if no card is available.
4048
if uid is None:

0 commit comments

Comments
 (0)