Merge pull request #32 from adafruit/pylint-update

Ran black, updated to pylint 2.x
This commit is contained in:
Kattni 2020-03-17 16:46:38 -04:00 committed by GitHub
commit af8fa2a00a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 353 additions and 299 deletions

View file

@ -40,7 +40,7 @@ jobs:
source actions-ci/install.sh
- name: Pip install pylint, black, & Sphinx
run: |
pip install --force-reinstall pylint==1.9.2 black==19.10b0 Sphinx sphinx-rtd-theme
pip install --force-reinstall pylint black==19.10b0 Sphinx sphinx-rtd-theme
- name: Library version
run: git describe --dirty --always --tags
- name: PyLint

View file

@ -55,114 +55,114 @@ __version__ = "0.0.0-auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_PN532.git"
# pylint: disable=bad-whitespace
_PREAMBLE = const(0x00)
_STARTCODE1 = const(0x00)
_STARTCODE2 = const(0xFF)
_POSTAMBLE = const(0x00)
_PREAMBLE = const(0x00)
_STARTCODE1 = const(0x00)
_STARTCODE2 = const(0xFF)
_POSTAMBLE = const(0x00)
_HOSTTOPN532 = const(0xD4)
_PN532TOHOST = const(0xD5)
_HOSTTOPN532 = const(0xD4)
_PN532TOHOST = const(0xD5)
# PN532 Commands
_COMMAND_DIAGNOSE = const(0x00)
_COMMAND_GETFIRMWAREVERSION = const(0x02)
_COMMAND_GETGENERALSTATUS = const(0x04)
_COMMAND_READREGISTER = const(0x06)
_COMMAND_WRITEREGISTER = const(0x08)
_COMMAND_READGPIO = const(0x0C)
_COMMAND_WRITEGPIO = const(0x0E)
_COMMAND_SETSERIALBAUDRATE = const(0x10)
_COMMAND_SETPARAMETERS = const(0x12)
_COMMAND_SAMCONFIGURATION = const(0x14)
_COMMAND_POWERDOWN = const(0x16)
_COMMAND_RFCONFIGURATION = const(0x32)
_COMMAND_RFREGULATIONTEST = const(0x58)
_COMMAND_INJUMPFORDEP = const(0x56)
_COMMAND_INJUMPFORPSL = const(0x46)
_COMMAND_INLISTPASSIVETARGET = const(0x4A)
_COMMAND_INATR = const(0x50)
_COMMAND_INPSL = const(0x4E)
_COMMAND_INDATAEXCHANGE = const(0x40)
_COMMAND_INCOMMUNICATETHRU = const(0x42)
_COMMAND_INDESELECT = const(0x44)
_COMMAND_INRELEASE = const(0x52)
_COMMAND_INSELECT = const(0x54)
_COMMAND_INAUTOPOLL = const(0x60)
_COMMAND_TGINITASTARGET = const(0x8C)
_COMMAND_TGSETGENERALBYTES = const(0x92)
_COMMAND_TGGETDATA = const(0x86)
_COMMAND_TGSETDATA = const(0x8E)
_COMMAND_TGSETMETADATA = const(0x94)
_COMMAND_DIAGNOSE = const(0x00)
_COMMAND_GETFIRMWAREVERSION = const(0x02)
_COMMAND_GETGENERALSTATUS = const(0x04)
_COMMAND_READREGISTER = const(0x06)
_COMMAND_WRITEREGISTER = const(0x08)
_COMMAND_READGPIO = const(0x0C)
_COMMAND_WRITEGPIO = const(0x0E)
_COMMAND_SETSERIALBAUDRATE = const(0x10)
_COMMAND_SETPARAMETERS = const(0x12)
_COMMAND_SAMCONFIGURATION = const(0x14)
_COMMAND_POWERDOWN = const(0x16)
_COMMAND_RFCONFIGURATION = const(0x32)
_COMMAND_RFREGULATIONTEST = const(0x58)
_COMMAND_INJUMPFORDEP = const(0x56)
_COMMAND_INJUMPFORPSL = const(0x46)
_COMMAND_INLISTPASSIVETARGET = const(0x4A)
_COMMAND_INATR = const(0x50)
_COMMAND_INPSL = const(0x4E)
_COMMAND_INDATAEXCHANGE = const(0x40)
_COMMAND_INCOMMUNICATETHRU = const(0x42)
_COMMAND_INDESELECT = const(0x44)
_COMMAND_INRELEASE = const(0x52)
_COMMAND_INSELECT = const(0x54)
_COMMAND_INAUTOPOLL = const(0x60)
_COMMAND_TGINITASTARGET = const(0x8C)
_COMMAND_TGSETGENERALBYTES = const(0x92)
_COMMAND_TGGETDATA = const(0x86)
_COMMAND_TGSETDATA = const(0x8E)
_COMMAND_TGSETMETADATA = const(0x94)
_COMMAND_TGGETINITIATORCOMMAND = const(0x88)
_COMMAND_TGRESPONSETOINITIATOR = const(0x90)
_COMMAND_TGGETTARGETSTATUS = const(0x8A)
_COMMAND_TGGETTARGETSTATUS = const(0x8A)
_RESPONSE_INDATAEXCHANGE = const(0x41)
_RESPONSE_INLISTPASSIVETARGET = const(0x4B)
_RESPONSE_INDATAEXCHANGE = const(0x41)
_RESPONSE_INLISTPASSIVETARGET = const(0x4B)
_WAKEUP = const(0x55)
_WAKEUP = const(0x55)
_MIFARE_ISO14443A = const(0x00)
_MIFARE_ISO14443A = const(0x00)
# Mifare Commands
MIFARE_CMD_AUTH_A = const(0x60)
MIFARE_CMD_AUTH_B = const(0x61)
MIFARE_CMD_READ = const(0x30)
MIFARE_CMD_WRITE = const(0xA0)
MIFARE_CMD_TRANSFER = const(0xB0)
MIFARE_CMD_DECREMENT = const(0xC0)
MIFARE_CMD_INCREMENT = const(0xC1)
MIFARE_CMD_STORE = const(0xC2)
MIFARE_ULTRALIGHT_CMD_WRITE = const(0xA2)
MIFARE_CMD_AUTH_A = const(0x60)
MIFARE_CMD_AUTH_B = const(0x61)
MIFARE_CMD_READ = const(0x30)
MIFARE_CMD_WRITE = const(0xA0)
MIFARE_CMD_TRANSFER = const(0xB0)
MIFARE_CMD_DECREMENT = const(0xC0)
MIFARE_CMD_INCREMENT = const(0xC1)
MIFARE_CMD_STORE = const(0xC2)
MIFARE_ULTRALIGHT_CMD_WRITE = const(0xA2)
# Prefixes for NDEF Records (to identify record type)
NDEF_URIPREFIX_NONE = const(0x00)
NDEF_URIPREFIX_HTTP_WWWDOT = const(0x01)
NDEF_URIPREFIX_HTTPS_WWWDOT = const(0x02)
NDEF_URIPREFIX_HTTP = const(0x03)
NDEF_URIPREFIX_HTTPS = const(0x04)
NDEF_URIPREFIX_TEL = const(0x05)
NDEF_URIPREFIX_MAILTO = const(0x06)
NDEF_URIPREFIX_FTP_ANONAT = const(0x07)
NDEF_URIPREFIX_FTP_FTPDOT = const(0x08)
NDEF_URIPREFIX_FTPS = const(0x09)
NDEF_URIPREFIX_SFTP = const(0x0A)
NDEF_URIPREFIX_SMB = const(0x0B)
NDEF_URIPREFIX_NFS = const(0x0C)
NDEF_URIPREFIX_FTP = const(0x0D)
NDEF_URIPREFIX_DAV = const(0x0E)
NDEF_URIPREFIX_NEWS = const(0x0F)
NDEF_URIPREFIX_TELNET = const(0x10)
NDEF_URIPREFIX_IMAP = const(0x11)
NDEF_URIPREFIX_RTSP = const(0x12)
NDEF_URIPREFIX_URN = const(0x13)
NDEF_URIPREFIX_POP = const(0x14)
NDEF_URIPREFIX_SIP = const(0x15)
NDEF_URIPREFIX_SIPS = const(0x16)
NDEF_URIPREFIX_TFTP = const(0x17)
NDEF_URIPREFIX_BTSPP = const(0x18)
NDEF_URIPREFIX_BTL2CAP = const(0x19)
NDEF_URIPREFIX_BTGOEP = const(0x1A)
NDEF_URIPREFIX_TCPOBEX = const(0x1B)
NDEF_URIPREFIX_IRDAOBEX = const(0x1C)
NDEF_URIPREFIX_FILE = const(0x1D)
NDEF_URIPREFIX_URN_EPC_ID = const(0x1E)
NDEF_URIPREFIX_URN_EPC_TAG = const(0x1F)
NDEF_URIPREFIX_URN_EPC_PAT = const(0x20)
NDEF_URIPREFIX_URN_EPC_RAW = const(0x21)
NDEF_URIPREFIX_URN_EPC = const(0x22)
NDEF_URIPREFIX_URN_NFC = const(0x23)
NDEF_URIPREFIX_NONE = const(0x00)
NDEF_URIPREFIX_HTTP_WWWDOT = const(0x01)
NDEF_URIPREFIX_HTTPS_WWWDOT = const(0x02)
NDEF_URIPREFIX_HTTP = const(0x03)
NDEF_URIPREFIX_HTTPS = const(0x04)
NDEF_URIPREFIX_TEL = const(0x05)
NDEF_URIPREFIX_MAILTO = const(0x06)
NDEF_URIPREFIX_FTP_ANONAT = const(0x07)
NDEF_URIPREFIX_FTP_FTPDOT = const(0x08)
NDEF_URIPREFIX_FTPS = const(0x09)
NDEF_URIPREFIX_SFTP = const(0x0A)
NDEF_URIPREFIX_SMB = const(0x0B)
NDEF_URIPREFIX_NFS = const(0x0C)
NDEF_URIPREFIX_FTP = const(0x0D)
NDEF_URIPREFIX_DAV = const(0x0E)
NDEF_URIPREFIX_NEWS = const(0x0F)
NDEF_URIPREFIX_TELNET = const(0x10)
NDEF_URIPREFIX_IMAP = const(0x11)
NDEF_URIPREFIX_RTSP = const(0x12)
NDEF_URIPREFIX_URN = const(0x13)
NDEF_URIPREFIX_POP = const(0x14)
NDEF_URIPREFIX_SIP = const(0x15)
NDEF_URIPREFIX_SIPS = const(0x16)
NDEF_URIPREFIX_TFTP = const(0x17)
NDEF_URIPREFIX_BTSPP = const(0x18)
NDEF_URIPREFIX_BTL2CAP = const(0x19)
NDEF_URIPREFIX_BTGOEP = const(0x1A)
NDEF_URIPREFIX_TCPOBEX = const(0x1B)
NDEF_URIPREFIX_IRDAOBEX = const(0x1C)
NDEF_URIPREFIX_FILE = const(0x1D)
NDEF_URIPREFIX_URN_EPC_ID = const(0x1E)
NDEF_URIPREFIX_URN_EPC_TAG = const(0x1F)
NDEF_URIPREFIX_URN_EPC_PAT = const(0x20)
NDEF_URIPREFIX_URN_EPC_RAW = const(0x21)
NDEF_URIPREFIX_URN_EPC = const(0x22)
NDEF_URIPREFIX_URN_NFC = const(0x23)
_GPIO_VALIDATIONBIT = const(0x80)
_GPIO_P30 = const(0)
_GPIO_P31 = const(1)
_GPIO_P32 = const(2)
_GPIO_P33 = const(3)
_GPIO_P34 = const(4)
_GPIO_P35 = const(5)
_GPIO_VALIDATIONBIT = const(0x80)
_GPIO_P30 = const(0)
_GPIO_P31 = const(1)
_GPIO_P32 = const(2)
_GPIO_P33 = const(3)
_GPIO_P34 = const(4)
_GPIO_P35 = const(5)
_ACK = b'\x00\x00\xFF\x00\xFF\x00'
_FRAME_START = b'\x00\x00\xFF'
_ACK = b"\x00\x00\xFF\x00\xFF\x00"
_FRAME_START = b"\x00\x00\xFF"
# pylint: enable=bad-whitespace
@ -179,7 +179,6 @@ def _reset(pin):
class BusyError(Exception):
"""Base class for exceptions in this module."""
pass
class PN532:
@ -223,7 +222,9 @@ class PN532:
def _write_frame(self, data):
"""Write a frame to the PN532 with the specified data bytearray."""
assert data is not None and 1 < len(data) < 255, 'Data must be array of 1 to 255 bytes.'
assert (
data is not None and 1 < len(data) < 255
), "Data must be array of 1 to 255 bytes."
# Build frame to send as:
# - Preamble (0x00)
# - Start code (0x00, 0xFF)
@ -233,7 +234,7 @@ class PN532:
# - Checksum
# - Postamble (0x00)
length = len(data)
frame = bytearray(length+8)
frame = bytearray(length + 8)
frame[0] = _PREAMBLE
frame[1] = _STARTCODE1
frame[2] = _STARTCODE2
@ -246,7 +247,7 @@ class PN532:
frame[-1] = _POSTAMBLE
# Send frame.
if self.debug:
print('Write frame: ', [hex(i) for i in frame])
print("Write frame: ", [hex(i) for i in frame])
self._write_data(bytes(frame))
def _read_frame(self, length):
@ -256,33 +257,37 @@ class PN532:
might be returned!
"""
# Read frame with expected length of data.
response = self._read_data(length+8)
response = self._read_data(length + 8)
if self.debug:
print('Read frame:', [hex(i) for i in response])
print("Read frame:", [hex(i) for i in response])
# Swallow all the 0x00 values that preceed 0xFF.
offset = 0
while response[offset] == 0x00:
offset += 1
if offset >= len(response):
raise RuntimeError('Response frame preamble does not contain 0x00FF!')
raise RuntimeError("Response frame preamble does not contain 0x00FF!")
if response[offset] != 0xFF:
raise RuntimeError('Response frame preamble does not contain 0x00FF!')
raise RuntimeError("Response frame preamble does not contain 0x00FF!")
offset += 1
if offset >= len(response):
raise RuntimeError('Response contains no data!')
raise RuntimeError("Response contains no data!")
# Check length & length checksum match.
frame_len = response[offset]
if (frame_len + response[offset+1]) & 0xFF != 0:
raise RuntimeError('Response length checksum did not match length!')
if (frame_len + response[offset + 1]) & 0xFF != 0:
raise RuntimeError("Response length checksum did not match length!")
# Check frame checksum value matches bytes.
checksum = sum(response[offset+2:offset+2+frame_len+1]) & 0xFF
checksum = sum(response[offset + 2 : offset + 2 + frame_len + 1]) & 0xFF
if checksum != 0:
raise RuntimeError('Response checksum did not match expected value: ', checksum)
raise RuntimeError(
"Response checksum did not match expected value: ", checksum
)
# Return frame data.
return response[offset+2:offset+2+frame_len]
return response[offset + 2 : offset + 2 + frame_len]
def call_function(self, command, response_length=0, params=[], timeout=1): # pylint: disable=dangerous-default-value
def call_function(
self, command, response_length=0, params=[], timeout=1
): # pylint: disable=dangerous-default-value
"""Send specified command to the PN532 and expect up to response_length
bytes back in a response. Note that less than the expected bytes might
be returned! Params can optionally specify an array of bytes to send as
@ -291,11 +296,11 @@ class PN532:
response is available within the timeout.
"""
# Build frame data with command and parameters.
data = bytearray(2+len(params))
data = bytearray(2 + len(params))
data[0] = _HOSTTOPN532
data[1] = command & 0xFF
for i, val in enumerate(params):
data[2+i] = val
data[2 + i] = val
# Send frame and wait for response.
try:
self._write_frame(data)
@ -306,14 +311,14 @@ class PN532:
return None
# Verify ACK response and wait to be ready for function response.
if not _ACK == self._read_data(len(_ACK)):
raise RuntimeError('Did not receive expected ACK from PN532!')
raise RuntimeError("Did not receive expected ACK from PN532!")
if not self._wait_ready(timeout):
return None
# Read response bytes.
response = self._read_frame(response_length+2)
response = self._read_frame(response_length + 2)
# Check that response is for the called function.
if not (response[0] == _PN532TOHOST and response[1] == (command+1)):
raise RuntimeError('Received unexpected command response!')
if not (response[0] == _PN532TOHOST and response[1] == (command + 1)):
raise RuntimeError("Received unexpected command response!")
# Return response data.
return response[2:]
@ -324,10 +329,10 @@ class PN532:
"""
response = self.call_function(_COMMAND_GETFIRMWAREVERSION, 4, timeout=0.5)
if response is None:
raise RuntimeError('Failed to detect the PN532')
raise RuntimeError("Failed to detect the PN532")
return tuple(response)
def SAM_configuration(self): # pylint: disable=invalid-name
def SAM_configuration(self): # pylint: disable=invalid-name
"""Configure the PN532 to read MiFare cards."""
# Send SAM configuration command with configuration for:
# - 0x01, normal mode
@ -344,24 +349,28 @@ class PN532:
"""
# Send passive read command for 1 card. Expect at most a 7 byte UUID.
try:
response = self.call_function(_COMMAND_INLISTPASSIVETARGET,
params=[0x01, card_baud],
response_length=19,
timeout=timeout)
response = self.call_function(
_COMMAND_INLISTPASSIVETARGET,
params=[0x01, card_baud],
response_length=19,
timeout=timeout,
)
except BusyError:
return None # no card found!
return None # no card found!
# If no response is available return None to indicate no card is present.
if response is None:
return None
# Check only 1 card with up to a 7 byte UID is present.
if response[0] != 0x01:
raise RuntimeError('More than one card detected!')
raise RuntimeError("More than one card detected!")
if response[5] > 7:
raise RuntimeError('Found card with unexpectedly long UID!')
raise RuntimeError("Found card with unexpectedly long UID!")
# Return UID of card.
return response[6:6+response[5]]
return response[6 : 6 + response[5]]
def mifare_classic_authenticate_block(self, uid, block_number, key_number, key): # pylint: disable=invalid-name
def mifare_classic_authenticate_block(
self, uid, block_number, key_number, key
): # pylint: disable=invalid-name
"""Authenticate specified block number for a MiFare classic card. Uid
should be a byte array with the UID of the card, block number should be
the block to authenticate, key number should be the key type (like
@ -372,16 +381,16 @@ class PN532:
# Build parameters for InDataExchange command to authenticate MiFare card.
uidlen = len(uid)
keylen = len(key)
params = bytearray(3+uidlen+keylen)
params = bytearray(3 + uidlen + keylen)
params[0] = 0x01 # Max card numbers
params[1] = key_number & 0xFF
params[2] = block_number & 0xFF
params[3:3+keylen] = key
params[3+keylen:] = uid
params[3 : 3 + keylen] = key
params[3 + keylen :] = uid
# Send InDataExchange request and verify response is 0x00.
response = self.call_function(_COMMAND_INDATAEXCHANGE,
params=params,
response_length=1)
response = self.call_function(
_COMMAND_INDATAEXCHANGE, params=params, response_length=1
)
return response[0] == 0x00
def mifare_classic_read_block(self, block_number):
@ -391,9 +400,11 @@ class PN532:
not read then None will be returned.
"""
# Send InDataExchange request to read block of MiFare data.
response = self.call_function(_COMMAND_INDATAEXCHANGE,
params=[0x01, MIFARE_CMD_READ, block_number & 0xFF],
response_length=17)
response = self.call_function(
_COMMAND_INDATAEXCHANGE,
params=[0x01, MIFARE_CMD_READ, block_number & 0xFF],
response_length=17,
)
# Check first response is 0x00 to show success.
if response[0] != 0x00:
return None
@ -406,7 +417,9 @@ class PN532:
write. If the data is successfully written then True is returned,
otherwise False is returned.
"""
assert data is not None and len(data) == 16, 'Data must be an array of 16 bytes!'
assert (
data is not None and len(data) == 16
), "Data must be an array of 16 bytes!"
# Build parameters for InDataExchange command to do MiFare classic write.
params = bytearray(19)
params[0] = 0x01 # Max card numbers
@ -414,9 +427,9 @@ class PN532:
params[2] = block_number & 0xFF
params[3:] = data
# Send InDataExchange request.
response = self.call_function(_COMMAND_INDATAEXCHANGE,
params=params,
response_length=1)
response = self.call_function(
_COMMAND_INDATAEXCHANGE, params=params, response_length=1
)
return response[0] == 0x0
def ntag2xx_write_block(self, block_number, data):
@ -425,17 +438,17 @@ class PN532:
write. If the data is successfully written then True is returned,
otherwise False is returned.
"""
assert data is not None and len(data) == 4, 'Data must be an array of 4 bytes!'
assert data is not None and len(data) == 4, "Data must be an array of 4 bytes!"
# Build parameters for InDataExchange command to do NTAG203 classic write.
params = bytearray(3+len(data))
params = bytearray(3 + len(data))
params[0] = 0x01 # Max card numbers
params[1] = MIFARE_ULTRALIGHT_CMD_WRITE
params[2] = block_number & 0xFF
params[3:] = data
# Send InDataExchange request.
response = self.call_function(_COMMAND_INDATAEXCHANGE,
params=params,
response_length=1)
response = self.call_function(
_COMMAND_INDATAEXCHANGE, params=params, response_length=1
)
return response[0] == 0x00
def ntag2xx_read_block(self, block_number):
@ -444,4 +457,6 @@ class PN532:
data starting at the specified block will be returned. If the block is
not read then None will be returned.
"""
return self.mifare_classic_read_block(block_number)[0:4] # only 4 bytes per page
return self.mifare_classic_read_block(block_number)[
0:4
] # only 4 bytes per page

View file

@ -44,10 +44,12 @@ from micropython import const
from adafruit_pn532.adafruit_pn532 import PN532, BusyError, _reset
# pylint: disable=bad-whitespace
_I2C_ADDRESS = const(0x24)
_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),
@ -61,7 +63,7 @@ class PN532_I2C(PN532):
self._i2c = i2c_device.I2CDevice(i2c, _I2C_ADDRESS)
super().__init__(debug=debug, reset=reset)
def _wakeup(self): # pylint: disable=no-self-use
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
@ -83,27 +85,26 @@ class PN532_I2C(PN532):
except OSError:
self._wakeup()
continue
if status == b'\x01':
if status == b"\x01":
return True # No longer busy
else:
time.sleep(0.05) # lets ask again soon!
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)
frame = bytearray(count + 1)
with self._i2c as i2c:
i2c.readinto(frame, end=1) # read status byte!
if frame[0] != 0x01: # not ready
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
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
return frame[1:] # don't return the status byte
def _write_data(self, framebytes):
"""Write a specified count of bytes to the PN532"""

View file

@ -43,10 +43,11 @@ 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)
_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
@ -54,14 +55,16 @@ def reverse_bit(num):
result = 0
for _ in range(8):
result <<= 1
result += (num & 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
@ -73,7 +76,7 @@ class PN532_SPI(PN532):
"""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
spi.write(bytearray([0x00])) # pylint: disable=no-member
time.sleep(1)
def _wait_ready(self, timeout=1):
@ -83,27 +86,28 @@ class PN532_SPI(PN532):
timestamp = time.monotonic()
with self._spi as spi:
while (time.monotonic() - timestamp) < timeout:
time.sleep(0.02) # required
spi.write_readinto(status_cmd, status_response) #pylint: disable=no-member
time.sleep(0.02) # required
spi.write_readinto(
status_cmd, status_response
) # pylint: disable=no-member
if reverse_bit(status_response[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
return True # Not busy anymore!
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)
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
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
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:]
@ -116,5 +120,5 @@ class PN532_SPI(PN532):
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
time.sleep(0.02) # required
spi.write(bytes(rev_frame)) # pylint: disable=no-member

View file

@ -41,8 +41,10 @@ __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.
@ -54,7 +56,7 @@ class PN532_UART(PN532):
def _wakeup(self):
"""Send any special commands/data to wake up PN532"""
#self._write_frame([_HOSTTOPN532, _COMMAND_SAMCONFIGURATION, 0x01])
# self._write_frame([_HOSTTOPN532, _COMMAND_SAMCONFIGURATION, 0x01])
self.SAM_configuration()
def _wait_ready(self, timeout=1):
@ -75,7 +77,11 @@ class PN532_UART(PN532):
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
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(
"\x55\x55\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
) # wake up!
self._uart.write(framebytes)

View file

@ -2,7 +2,8 @@
import os
import sys
sys.path.insert(0, os.path.abspath('..'))
sys.path.insert(0, os.path.abspath(".."))
# -- General configuration ------------------------------------------------
@ -10,10 +11,10 @@ sys.path.insert(0, os.path.abspath('..'))
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.intersphinx',
'sphinx.ext.napoleon',
'sphinx.ext.todo',
"sphinx.ext.autodoc",
"sphinx.ext.intersphinx",
"sphinx.ext.napoleon",
"sphinx.ext.todo",
]
# TODO: Please Read!
@ -23,29 +24,36 @@ extensions = [
autodoc_mock_imports = ["digitalio", "busio", "adafruit_bus_device", "micropython"]
intersphinx_mapping = {'python': ('https://docs.python.org/3.4', None),'BusDevice': ('https://circuitpython.readthedocs.io/projects/busdevice/en/latest/', None),'CircuitPython': ('https://circuitpython.readthedocs.io/en/latest/', None)}
intersphinx_mapping = {
"python": ("https://docs.python.org/3.4", None),
"BusDevice": (
"https://circuitpython.readthedocs.io/projects/busdevice/en/latest/",
None,
),
"CircuitPython": ("https://circuitpython.readthedocs.io/en/latest/", None),
}
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
templates_path = ["_templates"]
source_suffix = '.rst'
source_suffix = ".rst"
# The master toctree document.
master_doc = 'index'
master_doc = "index"
# General information about the project.
project = u'Adafruit PN532 Library'
copyright = u'2018 ladyada'
author = u'ladyada'
project = u"Adafruit PN532 Library"
copyright = u"2018 ladyada"
author = u"ladyada"
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = u'1.0'
version = u"1.0"
# The full version, including alpha/beta/rc tags.
release = u'1.0'
release = u"1.0"
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@ -57,7 +65,7 @@ language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '.env', 'CODE_OF_CONDUCT.md']
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", ".env", "CODE_OF_CONDUCT.md"]
# The reST default role (used for this markup: `text`) to use for all
# documents.
@ -69,7 +77,7 @@ default_role = "any"
add_function_parentheses = True
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
pygments_style = "sphinx"
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
@ -84,59 +92,62 @@ napoleon_numpy_docstring = False
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
on_rtd = os.environ.get("READTHEDOCS", None) == "True"
if not on_rtd: # only import and set the theme if we're building docs locally
try:
import sphinx_rtd_theme
html_theme = 'sphinx_rtd_theme'
html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), '.']
html_theme = "sphinx_rtd_theme"
html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), "."]
except:
html_theme = 'default'
html_theme_path = ['.']
html_theme = "default"
html_theme_path = ["."]
else:
html_theme_path = ['.']
html_theme_path = ["."]
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_static_path = ["_static"]
# The name of an image file (relative to this directory) to use as a favicon of
# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#
html_favicon = '_static/favicon.ico'
html_favicon = "_static/favicon.ico"
# Output file base name for HTML help builder.
htmlhelp_basename = 'AdafruitPn532Librarydoc'
htmlhelp_basename = "AdafruitPn532Librarydoc"
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'AdafruitPN532Library.tex', u'AdafruitPN532 Library Documentation',
author, 'manual'),
(
master_doc,
"AdafruitPN532Library.tex",
u"AdafruitPN532 Library Documentation",
author,
"manual",
),
]
# -- Options for manual page output ---------------------------------------
@ -144,8 +155,13 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'AdafruitPN532library', u'Adafruit PN532 Library Documentation',
[author], 1)
(
master_doc,
"AdafruitPN532library",
u"Adafruit PN532 Library Documentation",
[author],
1,
)
]
# -- Options for Texinfo output -------------------------------------------
@ -154,7 +170,13 @@ man_pages = [
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'AdafruitPN532Library', u'Adafruit PN532 Library Documentation',
author, 'AdafruitPN532Library', 'One line description of project.',
'Miscellaneous'),
(
master_doc,
"AdafruitPN532Library",
u"Adafruit PN532 Library Documentation",
author,
"AdafruitPN532Library",
"One line description of project.",
"Miscellaneous",
),
]

View file

@ -29,15 +29,17 @@ type RFID tag
import board
import busio
# Additional import needed for I2C/SPI
#from digitalio import DigitalInOut
# from digitalio import DigitalInOut
#
# NOTE: pick the import that matches the interface being used
#
from adafruit_pn532.adafruit_pn532 import MIFARE_CMD_AUTH_B
from adafruit_pn532.i2c import PN532_I2C
#from adafruit_pn532.spi import PN532_SPI
#from adafruit_pn532.uart import PN532_UART
# from adafruit_pn532.spi import PN532_SPI
# from adafruit_pn532.uart import PN532_UART
# I2C connection:
i2c = busio.I2C(board.SCL, board.SDA)
@ -47,42 +49,42 @@ pn532 = PN532_I2C(i2c, debug=False)
# With I2C, we recommend connecting RSTPD_N (reset) to a digital pin for manual
# harware reset
#reset_pin = DigitalInOut(board.D6)
# 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 = PN532_I2C(i2c, debug=False, reset=reset_pin, req=req_pin)
# req_pin = DigitalInOut(board.D12)
# 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 = PN532_SPI(spi, cs_pin, debug=False)
# spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
# cs_pin = DigitalInOut(board.D5)
# pn532 = PN532_SPI(spi, cs_pin, debug=False)
# UART connection
#uart = busio.UART(board.TX, board.RX, baudrate=115200, timeout=100)
#pn532 = PN532_UART(uart, debug=False)
# uart = busio.UART(board.TX, board.RX, baudrate=115200, timeout=100)
# pn532 = PN532_UART(uart, debug=False)
ic, ver, rev, support = pn532.firmware_version
print('Found PN532 with firmware version: {0}.{1}'.format(ver, rev))
print("Found PN532 with firmware version: {0}.{1}".format(ver, rev))
# Configure PN532 to communicate with MiFare cards
pn532.SAM_configuration()
print('Waiting for RFID/NFC card to write to!')
print("Waiting for RFID/NFC card to write to!")
key = b'\xFF\xFF\xFF\xFF\xFF\xFF'
key = b"\xFF\xFF\xFF\xFF\xFF\xFF"
while True:
# Check if a card is available to read
uid = pn532.read_passive_target(timeout=0.5)
print('.', end="")
print(".", end="")
# Try again if no card is available.
if uid is not None:
break
print("")
print('Found card with UID:', [hex(i) for i in uid])
print("Found card with UID:", [hex(i) for i in uid])
print("Authenticating block 4 ...")
authenticated = pn532.mifare_classic_authenticate_block(uid, 4, MIFARE_CMD_AUTH_B, key)
@ -91,10 +93,12 @@ if not authenticated:
# Set 16 bytes of block to 0xFEEDBEEF
data = bytearray(16)
data[0:16] = b'\xFE\xED\xBE\xEF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
data[0:16] = b"\xFE\xED\xBE\xEF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
# Write 16 byte block.
pn532.mifare_classic_write_block(4, data)
# Read block #6
print('Wrote to block 4, now trying to read that data:',
[hex(x) for x in pn532.mifare_classic_read_block(4)])
print(
"Wrote to block 4, now trying to read that data:",
[hex(x) for x in pn532.mifare_classic_read_block(4)],
)

View file

@ -28,26 +28,28 @@ type RFID tag
import board
import busio
from digitalio import DigitalInOut
#
# NOTE: pick the import that matches the interface being used
#
#from adafruit_pn532.i2c import PN532_I2C
# from adafruit_pn532.i2c import PN532_I2C
from adafruit_pn532.spi import PN532_SPI
#from adafruit_pn532.uart import PN532_UART
# from adafruit_pn532.uart import PN532_UART
# I2C connection:
#i2c = busio.I2C(board.SCL, board.SDA)
# i2c = busio.I2C(board.SCL, board.SDA)
# Non-hardware reset/request with I2C
#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
#reset_pin = DigitalInOut(board.D6)
# 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 = PN532_I2C(i2c, debug=False, reset=reset_pin, req=req_pin)
# req_pin = DigitalInOut(board.D12)
# pn532 = PN532_I2C(i2c, debug=False, reset=reset_pin, req=req_pin)
# SPI connection:
spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
@ -55,32 +57,34 @@ cs_pin = DigitalInOut(board.D5)
pn532 = PN532_SPI(spi, cs_pin, debug=False)
# UART connection
#uart = busio.UART(board.TX, board.RX, baudrate=115200, timeout=100)
#pn532 = PN532_UART(uart, debug=False)
# uart = busio.UART(board.TX, board.RX, baudrate=115200, timeout=100)
# pn532 = PN532_UART(uart, debug=False)
ic, ver, rev, support = pn532.firmware_version
print('Found PN532 with firmware version: {0}.{1}'.format(ver, rev))
print("Found PN532 with firmware version: {0}.{1}".format(ver, rev))
# Configure PN532 to communicate with MiFare cards
pn532.SAM_configuration()
print('Waiting for RFID/NFC card to write to!')
print("Waiting for RFID/NFC card to write to!")
while True:
# Check if a card is available to read
uid = pn532.read_passive_target(timeout=0.5)
print('.', end="")
print(".", end="")
# Try again if no card is available.
if uid is not None:
break
print("")
print('Found card with UID:', [hex(i) for i in uid])
print("Found card with UID:", [hex(i) for i in uid])
# Set 4 bytes of block to 0xFEEDBEEF
data = bytearray(4)
data[0:4] = b'\xFE\xED\xBE\xEF'
data[0:4] = b"\xFE\xED\xBE\xEF"
# Write 4 byte block.
pn532.ntag2xx_write_block(6, data)
# Read block #6
print('Wrote to block 6, now trying to read that data:',
[hex(x) for x in pn532.ntag2xx_read_block(6)])
print(
"Wrote to block 6, now trying to read that data:",
[hex(x) for x in pn532.ntag2xx_read_block(6)],
)

View file

@ -8,18 +8,20 @@ After initialization, try waving various 13.56MHz RFID cards over it!
import board
import busio
from digitalio import DigitalInOut
#
# 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
# 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 = 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
@ -30,26 +32,26 @@ req_pin = DigitalInOut(board.D12)
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 = PN532_SPI(spi, cs_pin, debug=False)
# spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
# cs_pin = DigitalInOut(board.D5)
# pn532 = PN532_SPI(spi, cs_pin, debug=False)
# UART connection
#uart = busio.UART(board.TX, board.RX, baudrate=115200, timeout=100)
#pn532 = PN532_UART(uart, debug=False)
# uart = busio.UART(board.TX, board.RX, baudrate=115200, timeout=100)
# pn532 = PN532_UART(uart, debug=False)
ic, ver, rev, support = pn532.firmware_version
print('Found PN532 with firmware version: {0}.{1}'.format(ver, rev))
print("Found PN532 with firmware version: {0}.{1}".format(ver, rev))
# Configure PN532 to communicate with MiFare cards
pn532.SAM_configuration()
print('Waiting for RFID/NFC card...')
print("Waiting for RFID/NFC card...")
while True:
# Check if a card is available to read
uid = pn532.read_passive_target(timeout=0.5)
print('.', end="")
print(".", end="")
# Try again if no card is available.
if uid is None:
continue
print('Found card with UID:', [hex(i) for i in uid])
print("Found card with UID:", [hex(i) for i in uid])

View file

@ -7,6 +7,7 @@ https://github.com/pypa/sampleproject
# Always prefer setuptools over distutils
from setuptools import setup, find_packages
# To use a consistent encoding
from codecs import open
from os import path
@ -14,47 +15,42 @@ from os import path
here = path.abspath(path.dirname(__file__))
# Get the long description from the README file
with open(path.join(here, 'README.rst'), encoding='utf-8') as f:
with open(path.join(here, "README.rst"), encoding="utf-8") as f:
long_description = f.read()
setup(
name='adafruit-circuitpython-pn532',
name="adafruit-circuitpython-pn532",
use_scm_version=True,
setup_requires=['setuptools_scm'],
description='CircuitPython library for controlling PN532 RFID/NFC reader-writer.',
setup_requires=["setuptools_scm"],
description="CircuitPython library for controlling PN532 RFID/NFC reader-writer.",
long_description=long_description,
long_description_content_type='text/x-rst',
long_description_content_type="text/x-rst",
# The project's main homepage.
url='https://github.com/adafruit/Adafruit_CircuitPython_PN532',
url="https://github.com/adafruit/Adafruit_CircuitPython_PN532",
# Author details
author='Adafruit Industries',
author_email='circuitpython@adafruit.com',
install_requires=['Adafruit-Blinka', 'adafruit-circuitpython-busdevice', 'pyserial'],
author="Adafruit Industries",
author_email="circuitpython@adafruit.com",
install_requires=[
"Adafruit-Blinka",
"adafruit-circuitpython-busdevice",
"pyserial",
],
# Choose your license
license='MIT',
license="MIT",
# See https://pypi.python.org/pypi?%3Aaction=list_classifiers
classifiers=[
'Development Status :: 3 - Alpha',
'Intended Audience :: Developers',
'Topic :: Software Development :: Libraries',
'Topic :: System :: Hardware',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"Topic :: Software Development :: Libraries",
"Topic :: System :: Hardware",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
],
# What does your project relate to?
keywords='adafruit pn532 rfid nfc hardware micropython circuitpython',
keywords="adafruit pn532 rfid nfc hardware micropython circuitpython",
# You can just specify the packages manually here if your project is
# simple. Or you can use find_packages().
packages=['adafruit_pn532'],
packages=["adafruit_pn532"],
)