Merge pull request #32 from adafruit/pylint-update
Ran black, updated to pylint 2.x
This commit is contained in:
commit
af8fa2a00a
10 changed files with 353 additions and 299 deletions
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"""
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
116
docs/conf.py
116
docs/conf.py
|
@ -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",
|
||||
),
|
||||
]
|
||||
|
|
|
@ -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)],
|
||||
)
|
||||
|
|
|
@ -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)],
|
||||
)
|
||||
|
|
|
@ -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])
|
||||
|
|
54
setup.py
54
setup.py
|
@ -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"],
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue