31
31
32
32
from micropython import const
33
33
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
+
34
42
__version__ = "0.0.0+auto.0"
35
43
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_PN532.git"
36
44
@@ -151,7 +159,13 @@ class BusyError(Exception):
151
159
class PN532 :
152
160
"""PN532 driver base, must be extended for I2C/SPI/UART interfacing"""
153
161
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 :
155
169
"""Create an instance of the PN532 class"""
156
170
self .low_power = True
157
171
self .debug = debug
@@ -160,26 +174,26 @@ def __init__(self, *, debug=False, irq=None, reset=None):
160
174
self .reset ()
161
175
_ = self .firmware_version
162
176
163
- def _read_data (self , count ) :
177
+ def _read_data (self , count : int ) -> Union [ bytes , bytearray ] :
164
178
# Read raw data from device, not including status bytes:
165
179
# Subclasses MUST implement this!
166
180
raise NotImplementedError
167
181
168
- def _write_data (self , framebytes ) :
182
+ def _write_data (self , framebytes : bytes ) -> None :
169
183
# Write raw bytestring data to device, not including status bytes:
170
184
# Subclasses MUST implement this!
171
185
raise NotImplementedError
172
186
173
- def _wait_ready (self , timeout ) :
187
+ def _wait_ready (self , timeout : float ) -> bool :
174
188
# Check if busy up to max length of 'timeout' seconds
175
189
# Subclasses MUST implement this!
176
190
raise NotImplementedError
177
191
178
- def _wakeup (self ):
192
+ def _wakeup (self ) -> None :
179
193
# Send special command to wake up
180
194
raise NotImplementedError
181
195
182
- def reset (self ):
196
+ def reset (self ) -> None :
183
197
"""Perform a hardware reset toggle and then wake up the PN532"""
184
198
if self ._reset_pin :
185
199
if self .debug :
@@ -191,7 +205,7 @@ def reset(self):
191
205
time .sleep (0.1 )
192
206
self ._wakeup ()
193
207
194
- def _write_frame (self , data ) :
208
+ def _write_frame (self , data : bytearray ) -> None :
195
209
"""Write a frame to the PN532 with the specified data bytearray."""
196
210
assert (
197
211
data is not None and 1 < len (data ) < 255
@@ -221,7 +235,7 @@ def _write_frame(self, data):
221
235
print ("Write frame: " , [hex (i ) for i in frame ])
222
236
self ._write_data (bytes (frame ))
223
237
224
- def _read_frame (self , length ) :
238
+ def _read_frame (self , length : int ) -> Union [ bytes , bytearray ] :
225
239
"""Read a response frame from the PN532 of at most length bytes in size.
226
240
Returns the data inside the frame if found, otherwise raises an exception
227
241
if there is an error parsing the frame. Note that less than length bytes
@@ -257,8 +271,12 @@ def _read_frame(self, length):
257
271
return response [offset + 2 : offset + 2 + frame_len ]
258
272
259
273
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 ]]:
262
280
"""Send specified command to the PN532 and expect up to response_length
263
281
bytes back in a response. Note that less than the expected bytes might
264
282
be returned! Params can optionally specify an array of bytes to send as
@@ -273,11 +291,11 @@ def call_function(
273
291
)
274
292
275
293
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 :
278
296
"""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.
281
299
"""
282
300
if self .low_power :
283
301
self ._wakeup ()
@@ -300,7 +318,9 @@ def send_command(
300
318
raise RuntimeError ("Did not receive expected ACK from PN532!" )
301
319
return True
302
320
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 ]]:
304
324
"""Process the response from the PN532 and expect up to response_length
305
325
bytes back in a response. Note that less than the expected bytes might
306
326
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):
317
337
# Return response data.
318
338
return response [2 :]
319
339
320
- def power_down (self ):
340
+ def power_down (self ) -> bool :
321
341
"""Put the PN532 into a low power state. If the reset pin is connected a
322
342
hard power down is performed, if not, a soft power down is performed
323
343
instead. Returns True if the PN532 was powered down successfully or
@@ -333,7 +353,7 @@ def power_down(self):
333
353
return self .low_power
334
354
335
355
@property
336
- def firmware_version (self ):
356
+ def firmware_version (self ) -> Tuple [ int , int , int , int ] :
337
357
"""Call PN532 GetFirmwareVersion function and return a tuple with the IC,
338
358
Ver, Rev, and Support values.
339
359
"""
@@ -342,7 +362,7 @@ def firmware_version(self):
342
362
raise RuntimeError ("Failed to detect the PN532" )
343
363
return tuple (response )
344
364
345
- def SAM_configuration (self ): # pylint: disable=invalid-name
365
+ def SAM_configuration (self ) -> None : # pylint: disable=invalid-name
346
366
"""Configure the PN532 to read MiFare cards."""
347
367
# Send SAM configuration command with configuration for:
348
368
# - 0x01, normal mode
@@ -352,7 +372,9 @@ def SAM_configuration(self): # pylint: disable=invalid-name
352
372
# check the command was executed as expected.
353
373
self .call_function (_COMMAND_SAMCONFIGURATION , params = [0x01 , 0x14 , 0x01 ])
354
374
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 ]:
356
378
"""Wait for a MiFare card to be available and return its UID when found.
357
379
Will wait up to timeout seconds and return None if no card is found,
358
380
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):
364
386
return None
365
387
return self .get_passive_target (timeout = timeout )
366
388
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 :
368
392
"""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
370
394
not also return the UID of a card! `get_passive_target` must be called
371
395
to read the UID when a card is found. If just looking to see if a card
372
396
is currently present use `read_passive_target` instead.
@@ -380,7 +404,9 @@ def listen_for_passive_target(self, card_baud=_MIFARE_ISO14443A, timeout=1):
380
404
return False # _COMMAND_INLISTPASSIVETARGET failed
381
405
return response
382
406
383
- def get_passive_target (self , timeout = 1 ):
407
+ def get_passive_target (
408
+ self , timeout : float = 1
409
+ ) -> Optional [Union [bytes , bytearray ]]:
384
410
"""Will wait up to timeout seconds and return None if no card is found,
385
411
otherwise a bytearray with the UID of the found card is returned.
386
412
`listen_for_passive_target` must have been called first in order to put
@@ -404,9 +430,13 @@ def get_passive_target(self, timeout=1):
404
430
# Return UID of card.
405
431
return response [6 : 6 + response [5 ]]
406
432
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 :
410
440
"""Authenticate specified block number for a MiFare classic card. Uid
411
441
should be a byte array with the UID of the card, block number should be
412
442
the block to authenticate, key number should be the key type (like
@@ -429,7 +459,9 @@ def mifare_classic_authenticate_block(
429
459
)
430
460
return response [0 ] == 0x00
431
461
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 ]]:
433
465
"""Read a block of data from the card. Block number should be the block
434
466
to read. If the block is successfully read a bytearray of length 16 with
435
467
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):
447
479
# Return first 4 bytes since 16 bytes are always returned.
448
480
return response [1 :]
449
481
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 :
451
485
"""Write a block of data to the card. Block number should be the block
452
486
to write and data should be a byte array of length 16 with the data to
453
487
write. If the data is successfully written then True is returned,
@@ -468,7 +502,7 @@ def mifare_classic_write_block(self, block_number, data):
468
502
)
469
503
return response [0 ] == 0x0
470
504
471
- def ntag2xx_write_block (self , block_number , data ) :
505
+ def ntag2xx_write_block (self , block_number : int , data : ReadableBuffer ) -> bool :
472
506
"""Write a block of data to the card. Block number should be the block
473
507
to write and data should be a byte array of length 4 with the data to
474
508
write. If the data is successfully written then True is returned,
@@ -487,7 +521,9 @@ def ntag2xx_write_block(self, block_number, data):
487
521
)
488
522
return response [0 ] == 0x00
489
523
490
- def ntag2xx_read_block (self , block_number ):
524
+ def ntag2xx_read_block (
525
+ self , block_number : int
526
+ ) -> Optional [Union [bytes , bytearray ]]:
491
527
"""Read a block of data from the card. Block number should be the block
492
528
to read. If the block is successfully read the first 4 bytes (after the
493
529
leading 0x00 byte) will be returned.
0 commit comments