diff --git a/.travis.yml b/.travis.yml index 6d72f7c..10a4d3b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ install: - pip install circuitpython-build-tools Sphinx sphinx-rtd-theme - pip install --force-reinstall pylint==1.9.2 script: -- pylint adafruit_pn532.py +- pylint adafruit_pn532/*.py - ([[ ! -d "examples" ]] || pylint --disable=missing-docstring,invalid-name,bad-whitespace examples/*.py) - circuitpython-build-bundles --filename_prefix adafruit-circuitpython-pn532 --library_location . diff --git a/adafruit_pn532/__init__.py b/adafruit_pn532/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/adafruit_pn532.py b/adafruit_pn532/adafruit_pn532.py similarity index 73% rename from adafruit_pn532.py rename to adafruit_pn532/adafruit_pn532.py index 8375d3c..b0818bd 100644 --- a/adafruit_pn532.py +++ b/adafruit_pn532/adafruit_pn532.py @@ -46,11 +46,8 @@ Implementation Notes * Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice """ - import time from digitalio import Direction -import adafruit_bus_device.i2c_device as i2c_device -import adafruit_bus_device.spi_device as spi_device from micropython import const @@ -105,13 +102,6 @@ _RESPONSE_INLISTPASSIVETARGET = const(0x4B) _WAKEUP = const(0x55) -_SPI_STATREAD = const(0x02) -_SPI_DATAWRITE = const(0x01) -_SPI_DATAREAD = const(0x03) -_SPI_READY = const(0x01) - -_I2C_ADDRESS = const(0x24) - _MIFARE_ISO14443A = const(0x00) # Mifare Commands @@ -186,22 +176,12 @@ def _reset(pin): pin.value = True time.sleep(0.1) -def reverse_bit(num): - """Turn an LSB byte to an MSB byte, and vice versa. Used for SPI as - it is LSB for the PN532, but 99% of SPI implementations are MSB only!""" - result = 0 - for _ in range(8): - result <<= 1 - result += (num & 1) - num >>= 1 - return result - - class BusyError(Exception): """Base class for exceptions in this module.""" pass + class PN532: """PN532 driver base, must be extended for I2C/SPI/UART interfacing""" @@ -464,167 +444,3 @@ class PN532: not read then None will be returned. """ return self.mifare_classic_read_block(block_number)[0:4] # only 4 bytes per page - -class PN532_UART(PN532): - """Driver for the PN532 connected over Serial UART""" - def __init__(self, uart, *, irq=None, reset=None, debug=False): - """Create an instance of the PN532 class using Serial connection. - Optional IRQ pin (not used), reset pin and debugging output. - """ - self.debug = debug - self._irq = irq - self._uart = uart - super().__init__(debug=debug, reset=reset) - - def _wakeup(self): - """Send any special commands/data to wake up PN532""" - #self._write_frame([_HOSTTOPN532, _COMMAND_SAMCONFIGURATION, 0x01]) - self.SAM_configuration() - - def _wait_ready(self, timeout=1): - """Wait `timeout` seconds""" - time.sleep(timeout) - return True - - def _read_data(self, count): - """Read a specified count of bytes from the PN532.""" - frame = self._uart.read(count) - if not frame: - raise BusyError("No data read from PN532") - if self.debug: - print("Reading: ", [hex(i) for i in frame]) - else: - time.sleep(0.1) - return frame - - def _write_data(self, framebytes): - """Write a specified count of bytes to the PN532""" - while self._uart.read(1): # this would be a lot nicer if we could query the # of bytes - pass - self._uart.write('\x55\x55\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') # wake up! - self._uart.write(framebytes) - -class PN532_I2C(PN532): - """Driver for the PN532 connected over I2C.""" - def __init__(self, i2c, *, irq=None, reset=None, req=None, debug=False): - """Create an instance of the PN532 class using I2C. Note that PN532 - uses clock stretching. Optional IRQ pin (not used), - reset pin and debugging output. - """ - self.debug = debug - self._irq = irq - self._req = req - if reset: - _reset(reset) - self._i2c = i2c_device.I2CDevice(i2c, _I2C_ADDRESS) - super().__init__(debug=debug, reset=reset) - - def _wakeup(self): # pylint: disable=no-self-use - """Send any special commands/data to wake up PN532""" - if self._req: - self._req.direction = Direction.OUTPUT - self._req.value = True - time.sleep(0.1) - self._req.value = False - time.sleep(0.1) - self._req.value = True - time.sleep(0.5) - - def _wait_ready(self, timeout=1): - """Poll PN532 if status byte is ready, up to `timeout` seconds""" - status = bytearray(1) - timestamp = time.monotonic() - while (time.monotonic() - timestamp) < timeout: - try: - with self._i2c: - self._i2c.readinto(status) - except OSError: - self._wakeup() - continue - if status == b'\x01': - return True # No longer busy - else: - time.sleep(0.05) # lets ask again soon! - # Timed out! - return False - - def _read_data(self, count): - """Read a specified count of bytes from the PN532.""" - # Build a read request frame. - frame = bytearray(count+1) - with self._i2c as i2c: - i2c.readinto(frame, end=1) # read status byte! - if frame[0] != 0x01: # not ready - raise BusyError - i2c.readinto(frame) # ok get the data, plus statusbyte - if self.debug: - print("Reading: ", [hex(i) for i in frame[1:]]) - else: - time.sleep(0.1) - return frame[1:] # don't return the status byte - - def _write_data(self, framebytes): - """Write a specified count of bytes to the PN532""" - with self._i2c as i2c: - i2c.write(framebytes) - -class PN532_SPI(PN532): - """Driver for the PN532 connected over SPI. Pass in a hardware or bitbang - SPI device & chip select digitalInOut pin. Optional IRQ pin (not used), - reset pin and debugging output.""" - def __init__(self, spi, cs_pin, *, irq=None, reset=None, debug=False): - """Create an instance of the PN532 class using SPI""" - self.debug = debug - self._irq = irq - self._spi = spi_device.SPIDevice(spi, cs_pin) - super().__init__(debug=debug, reset=reset) - - def _wakeup(self): - """Send any special commands/data to wake up PN532""" - with self._spi as spi: - time.sleep(1) - spi.write(bytearray([0x00])) #pylint: disable=no-member - time.sleep(1) - - 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 - - def _read_data(self, count): - """Read a specified count of bytes from the PN532.""" - # Build a read request frame. - frame = bytearray(count+1) - # Add the SPI data read signal byte, but LSB'ify it - frame[0] = reverse_bit(_SPI_DATAREAD) - - with self._spi as spi: - time.sleep(0.02) # required - spi.write_readinto(frame, frame) #pylint: disable=no-member - for i, val in enumerate(frame): - frame[i] = reverse_bit(val) # turn LSB data to MSB - if self.debug: - print("Reading: ", [hex(i) for i in frame[1:]]) - return frame[1:] - - def _write_data(self, framebytes): - """Write a specified count of bytes to the PN532""" - # start by making a frame with data write in front, - # then rest of bytes, and LSBify it - rev_frame = [reverse_bit(x) for x in bytes([_SPI_DATAWRITE]) + framebytes] - if self.debug: - print("Writing: ", [hex(i) for i in rev_frame]) - with self._spi as spi: - time.sleep(0.02) # required - spi.write(bytes(rev_frame)) #pylint: disable=no-member diff --git a/adafruit_pn532/i2c.py b/adafruit_pn532/i2c.py new file mode 100644 index 0000000..2d8054c --- /dev/null +++ b/adafruit_pn532/i2c.py @@ -0,0 +1,111 @@ +# Adafruit PN532 NFC/RFID control library. +# Author: Tony DiCola +# +# The MIT License (MIT) +# +# Copyright (c) 2015-2018 Adafruit Industries +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +""" +``adafruit_pn532.i2c`` +==================================================== + +This module will let you communicate with a PN532 RFID/NFC shield or breakout +using I2C. + +* Author(s): Original Raspberry Pi code by Tony DiCola, CircuitPython by ladyada, + refactor by Carter Nelson + +""" + +__version__ = "0.0.0-auto.0" +__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_PN532.git" + +import time +import adafruit_bus_device.i2c_device as i2c_device +from digitalio import Direction +from micropython import const +from adafruit_pn532.adafruit_pn532 import PN532, BusyError, _reset + +# pylint: disable=bad-whitespace +_I2C_ADDRESS = const(0x24) + +class PN532_I2C(PN532): + """Driver for the PN532 connected over I2C.""" + def __init__(self, i2c, *, irq=None, reset=None, req=None, debug=False): + """Create an instance of the PN532 class using I2C. Note that PN532 + uses clock stretching. Optional IRQ pin (not used), + reset pin and debugging output. + """ + self.debug = debug + self._irq = irq + self._req = req + if reset: + _reset(reset) + self._i2c = i2c_device.I2CDevice(i2c, _I2C_ADDRESS) + super().__init__(debug=debug, reset=reset) + + def _wakeup(self): # pylint: disable=no-self-use + """Send any special commands/data to wake up PN532""" + if self._req: + self._req.direction = Direction.OUTPUT + self._req.value = True + time.sleep(0.1) + self._req.value = False + time.sleep(0.1) + self._req.value = True + time.sleep(0.5) + + def _wait_ready(self, timeout=1): + """Poll PN532 if status byte is ready, up to `timeout` seconds""" + status = bytearray(1) + timestamp = time.monotonic() + while (time.monotonic() - timestamp) < timeout: + try: + with self._i2c: + self._i2c.readinto(status) + except OSError: + self._wakeup() + continue + if status == b'\x01': + return True # No longer busy + else: + time.sleep(0.05) # lets ask again soon! + # Timed out! + return False + + def _read_data(self, count): + """Read a specified count of bytes from the PN532.""" + # Build a read request frame. + frame = bytearray(count+1) + with self._i2c as i2c: + i2c.readinto(frame, end=1) # read status byte! + if frame[0] != 0x01: # not ready + raise BusyError + i2c.readinto(frame) # ok get the data, plus statusbyte + if self.debug: + print("Reading: ", [hex(i) for i in frame[1:]]) + else: + time.sleep(0.1) + return frame[1:] # don't return the status byte + + def _write_data(self, framebytes): + """Write a specified count of bytes to the PN532""" + with self._i2c as i2c: + i2c.write(framebytes) diff --git a/adafruit_pn532/spi.py b/adafruit_pn532/spi.py new file mode 100644 index 0000000..bd656d6 --- /dev/null +++ b/adafruit_pn532/spi.py @@ -0,0 +1,120 @@ +# Adafruit PN532 NFC/RFID control library. +# Author: Tony DiCola +# +# The MIT License (MIT) +# +# Copyright (c) 2015-2018 Adafruit Industries +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +""" +``adafruit_pn532.spi`` +==================================================== + +This module will let you communicate with a PN532 RFID/NFC shield or breakout +using SPI. + +* Author(s): Original Raspberry Pi code by Tony DiCola, CircuitPython by ladyada, + refactor by Carter Nelson + +""" + +__version__ = "0.0.0-auto.0" +__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_PN532.git" + +import time +import adafruit_bus_device.spi_device as spi_device +from micropython import const +from adafruit_pn532.adafruit_pn532 import PN532 + +# pylint: disable=bad-whitespace +_SPI_STATREAD = const(0x02) +_SPI_DATAWRITE = const(0x01) +_SPI_DATAREAD = const(0x03) +_SPI_READY = const(0x01) + +def reverse_bit(num): + """Turn an LSB byte to an MSB byte, and vice versa. Used for SPI as + it is LSB for the PN532, but 99% of SPI implementations are MSB only!""" + result = 0 + for _ in range(8): + result <<= 1 + result += (num & 1) + num >>= 1 + return result + +class PN532_SPI(PN532): + """Driver for the PN532 connected over SPI. Pass in a hardware or bitbang + SPI device & chip select digitalInOut pin. Optional IRQ pin (not used), + reset pin and debugging output.""" + def __init__(self, spi, cs_pin, *, irq=None, reset=None, debug=False): + """Create an instance of the PN532 class using SPI""" + self.debug = debug + self._irq = irq + self._spi = spi_device.SPIDevice(spi, cs_pin) + super().__init__(debug=debug, reset=reset) + + def _wakeup(self): + """Send any special commands/data to wake up PN532""" + with self._spi as spi: + time.sleep(1) + spi.write(bytearray([0x00])) #pylint: disable=no-member + time.sleep(1) + + 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 + + def _read_data(self, count): + """Read a specified count of bytes from the PN532.""" + # Build a read request frame. + frame = bytearray(count+1) + # Add the SPI data read signal byte, but LSB'ify it + frame[0] = reverse_bit(_SPI_DATAREAD) + + with self._spi as spi: + time.sleep(0.02) # required + spi.write_readinto(frame, frame) #pylint: disable=no-member + for i, val in enumerate(frame): + frame[i] = reverse_bit(val) # turn LSB data to MSB + if self.debug: + print("Reading: ", [hex(i) for i in frame[1:]]) + return frame[1:] + + def _write_data(self, framebytes): + """Write a specified count of bytes to the PN532""" + # start by making a frame with data write in front, + # then rest of bytes, and LSBify it + rev_frame = [reverse_bit(x) for x in bytes([_SPI_DATAWRITE]) + framebytes] + if self.debug: + print("Writing: ", [hex(i) for i in rev_frame]) + with self._spi as spi: + time.sleep(0.02) # required + spi.write(bytes(rev_frame)) #pylint: disable=no-member diff --git a/adafruit_pn532/uart.py b/adafruit_pn532/uart.py new file mode 100644 index 0000000..1faea84 --- /dev/null +++ b/adafruit_pn532/uart.py @@ -0,0 +1,81 @@ +# Adafruit PN532 NFC/RFID control library. +# Author: Tony DiCola +# +# The MIT License (MIT) +# +# Copyright (c) 2015-2018 Adafruit Industries +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +""" +``adafruit_pn532.uart`` +==================================================== + +This module will let you communicate with a PN532 RFID/NFC shield or breakout +using UART. + +* Author(s): Original Raspberry Pi code by Tony DiCola, CircuitPython by ladyada, + refactor by Carter Nelson + +""" + +__version__ = "0.0.0-auto.0" +__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_PN532.git" + + +import time +from adafruit_pn532.adafruit_pn532 import PN532, BusyError + +class PN532_UART(PN532): + """Driver for the PN532 connected over Serial UART""" + def __init__(self, uart, *, irq=None, reset=None, debug=False): + """Create an instance of the PN532 class using Serial connection. + Optional IRQ pin (not used), reset pin and debugging output. + """ + self.debug = debug + self._irq = irq + self._uart = uart + super().__init__(debug=debug, reset=reset) + + def _wakeup(self): + """Send any special commands/data to wake up PN532""" + #self._write_frame([_HOSTTOPN532, _COMMAND_SAMCONFIGURATION, 0x01]) + self.SAM_configuration() + + def _wait_ready(self, timeout=1): + """Wait `timeout` seconds""" + time.sleep(timeout) + return True + + def _read_data(self, count): + """Read a specified count of bytes from the PN532.""" + frame = self._uart.read(count) + if not frame: + raise BusyError("No data read from PN532") + if self.debug: + print("Reading: ", [hex(i) for i in frame]) + else: + time.sleep(0.1) + return frame + + def _write_data(self, framebytes): + """Write a specified count of bytes to the PN532""" + while self._uart.read(1): # this would be a lot nicer if we could query the # of bytes + pass + self._uart.write('\x55\x55\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') # wake up! + self._uart.write(framebytes) diff --git a/docs/api.rst b/docs/api.rst index 3c1bb47..164f9e8 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -4,5 +4,14 @@ .. If your library file(s) are nested in a directory (e.g. /adafruit_foo/foo.py) .. use this format as the module name: "adafruit_foo.foo" -.. automodule:: adafruit_pn532 +.. automodule:: adafruit_pn532.adafruit_pn532 + :members: + +.. automodule:: adafruit_pn532.i2c + :members: + +.. automodule:: adafruit_pn532.spi + :members: + +.. automodule:: adafruit_pn532.uart :members: diff --git a/examples/pn532_simpletest.py b/examples/pn532_simpletest.py index cdd98f3..050931a 100644 --- a/examples/pn532_simpletest.py +++ b/examples/pn532_simpletest.py @@ -8,13 +8,18 @@ After initialization, try waving various 13.56MHz RFID cards over it! import board import busio from digitalio import DigitalInOut -import adafruit_pn532 +# +# NOTE: pick the import that matches the interface being used +# +from adafruit_pn532.i2c import PN532_I2C +#from adafruit_pn532.spi import PN532_SPI +#from adafruit_pn532.uart import PN532_UART # I2C connection: i2c = busio.I2C(board.SCL, board.SDA) # Non-hardware -#pn532 = adafruit_pn532.PN532_I2C(i2c, debug=False) +#pn532 = PN532_I2C(i2c, debug=False) # With I2C, we recommend connecting RSTPD_N (reset) to a digital pin for manual # harware reset @@ -22,16 +27,16 @@ reset_pin = DigitalInOut(board.D6) # On Raspberry Pi, you must also connect a pin to P32 "H_Request" for hardware # wakeup! this means we don't need to do the I2C clock-stretch thing req_pin = DigitalInOut(board.D12) -pn532 = adafruit_pn532.PN532_I2C(i2c, debug=False, reset=reset_pin, req=req_pin) +pn532 = PN532_I2C(i2c, debug=False, reset=reset_pin, req=req_pin) # SPI connection: #spi = busio.SPI(board.SCK, board.MOSI, board.MISO) #cs_pin = DigitalInOut(board.D5) -#pn532 = adafruit_pn532.PN532_SPI(spi, cs_pin, debug=False) +#pn532 = PN532_SPI(spi, cs_pin, debug=False) # UART connection #uart = busio.UART(board.TX, board.RX, baudrate=115200, timeout=100) -#pn532 = adafruit_pn532.PN532_UART(uart, debug=False) +#pn532 = PN532_UART(uart, debug=False) ic, ver, rev, support = pn532.get_firmware_version() print('Found PN532 with firmware version: {0}.{1}'.format(ver, rev)) diff --git a/examples/readwrite_ntag2xx.py b/examples/readwrite_ntag2xx.py index 1961427..0ac47a4 100644 --- a/examples/readwrite_ntag2xx.py +++ b/examples/readwrite_ntag2xx.py @@ -28,13 +28,18 @@ type RFID tag import board import busio from digitalio import DigitalInOut -import adafruit_pn532 +# +# NOTE: pick the import that matches the interface being used +# +#from adafruit_pn532.i2c import PN532_I2C +from adafruit_pn532.spi import PN532_SPI +#from adafruit_pn532.uart import PN532_UART # I2C connection: #i2c = busio.I2C(board.SCL, board.SDA) # Non-hardware reset/request with I2C -#pn532 = adafruit_pn532.PN532_I2C(i2c, debug=False) +#pn532 = PN532_I2C(i2c, debug=False) # With I2C, we recommend connecting RSTPD_N (reset) to a digital pin for manual # harware reset @@ -42,16 +47,16 @@ import adafruit_pn532 # On Raspberry Pi, you must also connect a pin to P32 "H_Request" for hardware # wakeup! this means we don't need to do the I2C clock-stretch thing #req_pin = DigitalInOut(board.D12) -#pn532 = adafruit_pn532.PN532_I2C(i2c, debug=False, reset=reset_pin, req=req_pin) +#pn532 = PN532_I2C(i2c, debug=False, reset=reset_pin, req=req_pin) # SPI connection: spi = busio.SPI(board.SCK, board.MOSI, board.MISO) cs_pin = DigitalInOut(board.D5) -pn532 = adafruit_pn532.PN532_SPI(spi, cs_pin, debug=False) +pn532 = PN532_SPI(spi, cs_pin, debug=False) # UART connection #uart = busio.UART(board.TX, board.RX, baudrate=115200, timeout=100) -#pn532 = adafruit_pn532.PN532_UART(uart, debug=False) +#pn532 = PN532_UART(uart, debug=False) ic, ver, rev, support = pn532.get_firmware_version() print('Found PN532 with firmware version: {0}.{1}'.format(ver, rev))