Skip to content

Commit 0061f33

Browse files
authored
Merge pull request #64 from tcfranks/main
resubmit pr Typting Annotations
2 parents a7287d2 + 812235c commit 0061f33

File tree

5 files changed

+124
-47
lines changed

5 files changed

+124
-47
lines changed

adafruit_pn532/adafruit_pn532.py

Lines changed: 65 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@
3131

3232
from micropython import const
3333

34+
try:
35+
from typing import Optional, Tuple, Union
36+
from typing_extensions import Literal
37+
from circuitpython_typing import ReadableBuffer
38+
from digitalio import DigitalInOut # pylint: disable=ungrouped-imports
39+
except ImportError:
40+
pass
41+
3442
__version__ = "0.0.0+auto.0"
3543
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_PN532.git"
3644

@@ -151,7 +159,13 @@ class BusyError(Exception):
151159
class PN532:
152160
"""PN532 driver base, must be extended for I2C/SPI/UART interfacing"""
153161

154-
def __init__(self, *, debug=False, irq=None, reset=None):
162+
def __init__(
163+
self,
164+
*,
165+
debug: bool = False,
166+
irq: Optional[DigitalInOut] = None,
167+
reset: Optional[DigitalInOut] = None
168+
) -> None:
155169
"""Create an instance of the PN532 class"""
156170
self.low_power = True
157171
self.debug = debug
@@ -160,26 +174,26 @@ def __init__(self, *, debug=False, irq=None, reset=None):
160174
self.reset()
161175
_ = self.firmware_version
162176

163-
def _read_data(self, count):
177+
def _read_data(self, count: int) -> Union[bytes, bytearray]:
164178
# Read raw data from device, not including status bytes:
165179
# Subclasses MUST implement this!
166180
raise NotImplementedError
167181

168-
def _write_data(self, framebytes):
182+
def _write_data(self, framebytes: bytes) -> None:
169183
# Write raw bytestring data to device, not including status bytes:
170184
# Subclasses MUST implement this!
171185
raise NotImplementedError
172186

173-
def _wait_ready(self, timeout):
187+
def _wait_ready(self, timeout: float) -> bool:
174188
# Check if busy up to max length of 'timeout' seconds
175189
# Subclasses MUST implement this!
176190
raise NotImplementedError
177191

178-
def _wakeup(self):
192+
def _wakeup(self) -> None:
179193
# Send special command to wake up
180194
raise NotImplementedError
181195

182-
def reset(self):
196+
def reset(self) -> None:
183197
"""Perform a hardware reset toggle and then wake up the PN532"""
184198
if self._reset_pin:
185199
if self.debug:
@@ -191,7 +205,7 @@ def reset(self):
191205
time.sleep(0.1)
192206
self._wakeup()
193207

194-
def _write_frame(self, data):
208+
def _write_frame(self, data: bytearray) -> None:
195209
"""Write a frame to the PN532 with the specified data bytearray."""
196210
assert (
197211
data is not None and 1 < len(data) < 255
@@ -221,7 +235,7 @@ def _write_frame(self, data):
221235
print("Write frame: ", [hex(i) for i in frame])
222236
self._write_data(bytes(frame))
223237

224-
def _read_frame(self, length):
238+
def _read_frame(self, length: int) -> Union[bytes, bytearray]:
225239
"""Read a response frame from the PN532 of at most length bytes in size.
226240
Returns the data inside the frame if found, otherwise raises an exception
227241
if there is an error parsing the frame. Note that less than length bytes
@@ -257,8 +271,12 @@ def _read_frame(self, length):
257271
return response[offset + 2 : offset + 2 + frame_len]
258272

259273
def call_function(
260-
self, command, response_length=0, params=[], timeout=1
261-
): # pylint: disable=dangerous-default-value
274+
self,
275+
command: int,
276+
response_length: int = 0,
277+
params: ReadableBuffer = b"",
278+
timeout: float = 1,
279+
) -> Optional[Union[bytes, bytearray]]:
262280
"""Send specified command to the PN532 and expect up to response_length
263281
bytes back in a response. Note that less than the expected bytes might
264282
be returned! Params can optionally specify an array of bytes to send as
@@ -273,11 +291,11 @@ def call_function(
273291
)
274292

275293
def send_command(
276-
self, command, params=[], timeout=1
277-
): # pylint: disable=dangerous-default-value
294+
self, command: int, params: ReadableBuffer = b"", timeout: float = 1
295+
) -> bool:
278296
"""Send specified command to the PN532 and wait for an acknowledgment.
279-
Will wait up to timeout seconds for the acknowlegment and return True.
280-
If no acknowlegment is received, False is returned.
297+
Will wait up to timeout seconds for the acknowledgment and return True.
298+
If no acknowledgment is received, False is returned.
281299
"""
282300
if self.low_power:
283301
self._wakeup()
@@ -300,7 +318,9 @@ def send_command(
300318
raise RuntimeError("Did not receive expected ACK from PN532!")
301319
return True
302320

303-
def process_response(self, command, response_length=0, timeout=1):
321+
def process_response(
322+
self, command: int, response_length: int = 0, timeout: float = 1
323+
) -> Optional[Union[bytes, bytearray]]:
304324
"""Process the response from the PN532 and expect up to response_length
305325
bytes back in a response. Note that less than the expected bytes might
306326
be returned! Will wait up to timeout seconds for a response and return
@@ -317,7 +337,7 @@ def process_response(self, command, response_length=0, timeout=1):
317337
# Return response data.
318338
return response[2:]
319339

320-
def power_down(self):
340+
def power_down(self) -> bool:
321341
"""Put the PN532 into a low power state. If the reset pin is connected a
322342
hard power down is performed, if not, a soft power down is performed
323343
instead. Returns True if the PN532 was powered down successfully or
@@ -333,7 +353,7 @@ def power_down(self):
333353
return self.low_power
334354

335355
@property
336-
def firmware_version(self):
356+
def firmware_version(self) -> Tuple[int, int, int, int]:
337357
"""Call PN532 GetFirmwareVersion function and return a tuple with the IC,
338358
Ver, Rev, and Support values.
339359
"""
@@ -342,7 +362,7 @@ def firmware_version(self):
342362
raise RuntimeError("Failed to detect the PN532")
343363
return tuple(response)
344364

345-
def SAM_configuration(self): # pylint: disable=invalid-name
365+
def SAM_configuration(self) -> None: # pylint: disable=invalid-name
346366
"""Configure the PN532 to read MiFare cards."""
347367
# Send SAM configuration command with configuration for:
348368
# - 0x01, normal mode
@@ -352,7 +372,9 @@ def SAM_configuration(self): # pylint: disable=invalid-name
352372
# check the command was executed as expected.
353373
self.call_function(_COMMAND_SAMCONFIGURATION, params=[0x01, 0x14, 0x01])
354374

355-
def read_passive_target(self, card_baud=_MIFARE_ISO14443A, timeout=1):
375+
def read_passive_target(
376+
self, card_baud: int = _MIFARE_ISO14443A, timeout: float = 1
377+
) -> Optional[bytearray]:
356378
"""Wait for a MiFare card to be available and return its UID when found.
357379
Will wait up to timeout seconds and return None if no card is found,
358380
otherwise a bytearray with the UID of the found card is returned.
@@ -364,9 +386,11 @@ def read_passive_target(self, card_baud=_MIFARE_ISO14443A, timeout=1):
364386
return None
365387
return self.get_passive_target(timeout=timeout)
366388

367-
def listen_for_passive_target(self, card_baud=_MIFARE_ISO14443A, timeout=1):
389+
def listen_for_passive_target(
390+
self, card_baud: int = _MIFARE_ISO14443A, timeout: float = 1
391+
) -> bool:
368392
"""Send command to PN532 to begin listening for a Mifare card. This
369-
returns True if the command was received succesfully. Note, this does
393+
returns True if the command was received successfully. Note, this does
370394
not also return the UID of a card! `get_passive_target` must be called
371395
to read the UID when a card is found. If just looking to see if a card
372396
is currently present use `read_passive_target` instead.
@@ -380,7 +404,9 @@ def listen_for_passive_target(self, card_baud=_MIFARE_ISO14443A, timeout=1):
380404
return False # _COMMAND_INLISTPASSIVETARGET failed
381405
return response
382406

383-
def get_passive_target(self, timeout=1):
407+
def get_passive_target(
408+
self, timeout: float = 1
409+
) -> Optional[Union[bytes, bytearray]]:
384410
"""Will wait up to timeout seconds and return None if no card is found,
385411
otherwise a bytearray with the UID of the found card is returned.
386412
`listen_for_passive_target` must have been called first in order to put
@@ -404,9 +430,13 @@ def get_passive_target(self, timeout=1):
404430
# Return UID of card.
405431
return response[6 : 6 + response[5]]
406432

407-
def mifare_classic_authenticate_block(
408-
self, uid, block_number, key_number, key
409-
): # pylint: disable=invalid-name
433+
def mifare_classic_authenticate_block( # pylint: disable=invalid-name
434+
self,
435+
uid: ReadableBuffer,
436+
block_number: int,
437+
key_number: Literal[0x60, 0x61],
438+
key: ReadableBuffer,
439+
) -> bool:
410440
"""Authenticate specified block number for a MiFare classic card. Uid
411441
should be a byte array with the UID of the card, block number should be
412442
the block to authenticate, key number should be the key type (like
@@ -429,7 +459,9 @@ def mifare_classic_authenticate_block(
429459
)
430460
return response[0] == 0x00
431461

432-
def mifare_classic_read_block(self, block_number):
462+
def mifare_classic_read_block(
463+
self, block_number: int
464+
) -> Optional[Union[bytes, bytearray]]:
433465
"""Read a block of data from the card. Block number should be the block
434466
to read. If the block is successfully read a bytearray of length 16 with
435467
data starting at the specified block will be returned. If the block is
@@ -447,7 +479,9 @@ def mifare_classic_read_block(self, block_number):
447479
# Return first 4 bytes since 16 bytes are always returned.
448480
return response[1:]
449481

450-
def mifare_classic_write_block(self, block_number, data):
482+
def mifare_classic_write_block(
483+
self, block_number: int, data: ReadableBuffer
484+
) -> bool:
451485
"""Write a block of data to the card. Block number should be the block
452486
to write and data should be a byte array of length 16 with the data to
453487
write. If the data is successfully written then True is returned,
@@ -468,7 +502,7 @@ def mifare_classic_write_block(self, block_number, data):
468502
)
469503
return response[0] == 0x0
470504

471-
def ntag2xx_write_block(self, block_number, data):
505+
def ntag2xx_write_block(self, block_number: int, data: ReadableBuffer) -> bool:
472506
"""Write a block of data to the card. Block number should be the block
473507
to write and data should be a byte array of length 4 with the data to
474508
write. If the data is successfully written then True is returned,
@@ -487,7 +521,9 @@ def ntag2xx_write_block(self, block_number, data):
487521
)
488522
return response[0] == 0x00
489523

490-
def ntag2xx_read_block(self, block_number):
524+
def ntag2xx_read_block(
525+
self, block_number: int
526+
) -> Optional[Union[bytes, bytearray]]:
491527
"""Read a block of data from the card. Block number should be the block
492528
to read. If the block is successfully read the first 4 bytes (after the
493529
leading 0x00 byte) will be returned.

adafruit_pn532/i2c.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,29 @@
2323
from micropython import const
2424
from adafruit_pn532.adafruit_pn532 import PN532, BusyError
2525

26+
try:
27+
from typing import Optional
28+
from digitalio import DigitalInOut # pylint: disable=ungrouped-imports
29+
from busio import I2C
30+
except ImportError:
31+
pass
32+
2633
_I2C_ADDRESS = const(0x24)
2734

2835

2936
class PN532_I2C(PN532):
3037
"""Driver for the PN532 connected over I2C."""
3138

3239
def __init__(
33-
self, i2c, address=_I2C_ADDRESS, *, irq=None, reset=None, req=None, debug=False
34-
):
40+
self,
41+
i2c: I2C,
42+
address: int = _I2C_ADDRESS,
43+
*,
44+
irq: Optional[DigitalInOut] = None,
45+
reset: Optional[DigitalInOut] = None,
46+
req: Optional[DigitalInOut] = None,
47+
debug: bool = False
48+
) -> None:
3549
"""Create an instance of the PN532 class using I2C. Note that PN532
3650
uses clock stretching. Optional IRQ pin (not used),
3751
resetp pin and debugging output.
@@ -41,7 +55,7 @@ def __init__(
4155
self._i2c = i2c_device.I2CDevice(i2c, address)
4256
super().__init__(debug=debug, irq=irq, reset=reset)
4357

44-
def _wakeup(self):
58+
def _wakeup(self) -> None:
4559
"""Send any special commands/data to wake up PN532"""
4660
if self._reset_pin:
4761
self._reset_pin.value = True
@@ -55,7 +69,7 @@ def _wakeup(self):
5569
self.low_power = False
5670
self.SAM_configuration() # Put the PN532 back in normal mode
5771

58-
def _wait_ready(self, timeout=1):
72+
def _wait_ready(self, timeout: float = 1) -> bool:
5973
"""Poll PN532 if status byte is ready, up to `timeout` seconds"""
6074
status = bytearray(1)
6175
timestamp = time.monotonic()
@@ -67,11 +81,11 @@ def _wait_ready(self, timeout=1):
6781
continue
6882
if status == b"\x01":
6983
return True # No longer busy
70-
time.sleep(0.01) # lets ask again soon!
84+
time.sleep(0.01) # let's ask again soon!
7185
# Timed out!
7286
return False
7387

74-
def _read_data(self, count):
88+
def _read_data(self, count: int) -> bytearray:
7589
"""Read a specified count of bytes from the PN532."""
7690
# Build a read request frame.
7791
frame = bytearray(count + 1)
@@ -84,7 +98,7 @@ def _read_data(self, count):
8498
print("Reading: ", [hex(i) for i in frame[1:]])
8599
return frame[1:] # don't return the status byte
86100

87-
def _write_data(self, framebytes):
101+
def _write_data(self, framebytes: bytes) -> None:
88102
"""Write a specified count of bytes to the PN532"""
89103
with self._i2c as i2c:
90104
i2c.write(framebytes)

adafruit_pn532/spi.py

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@
1414
1515
"""
1616

17+
try:
18+
from typing import Optional
19+
from circuitpython_typing import ReadableBuffer
20+
from digitalio import DigitalInOut
21+
from busio import SPI
22+
except ImportError:
23+
pass
24+
1725
__version__ = "0.0.0+auto.0"
1826
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_PN532.git"
1927

@@ -28,7 +36,7 @@
2836
_SPI_READY = const(0x01)
2937

3038

31-
def reverse_bit(num):
39+
def reverse_bit(num: int) -> int:
3240
"""Turn an LSB byte to an MSB byte, and vice versa. Used for SPI as
3341
it is LSB for the PN532, but 99% of SPI implementations are MSB only!"""
3442
result = 0
@@ -44,13 +52,21 @@ class PN532_SPI(PN532):
4452
SPI device & chip select digitalInOut pin. Optional IRQ pin (not used),
4553
reset pin and debugging output."""
4654

47-
def __init__(self, spi, cs_pin, *, irq=None, reset=None, debug=False):
55+
def __init__(
56+
self,
57+
spi: SPI,
58+
cs_pin: DigitalInOut,
59+
*,
60+
irq: Optional[DigitalInOut] = None,
61+
reset: Optional[DigitalInOut] = None,
62+
debug: bool = False
63+
) -> None:
4864
"""Create an instance of the PN532 class using SPI"""
4965
self.debug = debug
5066
self._spi = spi_device.SPIDevice(spi, cs_pin)
5167
super().__init__(debug=debug, irq=irq, reset=reset)
5268

53-
def _wakeup(self):
69+
def _wakeup(self) -> None:
5470
"""Send any special commands/data to wake up PN532"""
5571
if self._reset_pin:
5672
self._reset_pin.value = True
@@ -61,7 +77,7 @@ def _wakeup(self):
6177
self.low_power = False
6278
self.SAM_configuration() # Put the PN532 back in normal mode
6379

64-
def _wait_ready(self, timeout=1):
80+
def _wait_ready(self, timeout: float = 1) -> bool:
6581
"""Poll PN532 if status byte is ready, up to `timeout` seconds"""
6682
status_cmd = bytearray([reverse_bit(_SPI_STATREAD), 0x00])
6783
status_response = bytearray([0x00, 0x00])
@@ -77,7 +93,7 @@ def _wait_ready(self, timeout=1):
7793
# We timed out!
7894
return False
7995

80-
def _read_data(self, count):
96+
def _read_data(self, count: int) -> bytearray:
8197
"""Read a specified count of bytes from the PN532."""
8298
# Build a read request frame.
8399
frame = bytearray(count + 1)
@@ -92,7 +108,7 @@ def _read_data(self, count):
92108
print("Reading: ", [hex(i) for i in frame[1:]])
93109
return frame[1:]
94110

95-
def _write_data(self, framebytes):
111+
def _write_data(self, framebytes: ReadableBuffer) -> None:
96112
"""Write a specified count of bytes to the PN532"""
97113
# start by making a frame with data write in front,
98114
# then rest of bytes, and LSBify it

0 commit comments

Comments
 (0)