|
46 | 46 | * Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
|
47 | 47 | """
|
48 | 48 |
|
49 |
| - |
50 | 49 | import time
|
51 | 50 | from digitalio import Direction
|
52 |
| -import adafruit_bus_device.i2c_device as i2c_device |
53 |
| -import adafruit_bus_device.spi_device as spi_device |
54 | 51 |
|
55 | 52 | from micropython import const
|
56 | 53 |
|
|
105 | 102 |
|
106 | 103 | _WAKEUP = const(0x55)
|
107 | 104 |
|
108 |
| -_SPI_STATREAD = const(0x02) |
109 |
| -_SPI_DATAWRITE = const(0x01) |
110 |
| -_SPI_DATAREAD = const(0x03) |
111 |
| -_SPI_READY = const(0x01) |
112 |
| - |
113 |
| -_I2C_ADDRESS = const(0x24) |
114 |
| - |
115 | 105 | _MIFARE_ISO14443A = const(0x00)
|
116 | 106 |
|
117 | 107 | # Mifare Commands
|
@@ -186,22 +176,12 @@ def _reset(pin):
|
186 | 176 | pin.value = True
|
187 | 177 | time.sleep(0.1)
|
188 | 178 |
|
189 |
| -def reverse_bit(num): |
190 |
| - """Turn an LSB byte to an MSB byte, and vice versa. Used for SPI as |
191 |
| - it is LSB for the PN532, but 99% of SPI implementations are MSB only!""" |
192 |
| - result = 0 |
193 |
| - for _ in range(8): |
194 |
| - result <<= 1 |
195 |
| - result += (num & 1) |
196 |
| - num >>= 1 |
197 |
| - return result |
198 |
| - |
199 |
| - |
200 | 179 |
|
201 | 180 | class BusyError(Exception):
|
202 | 181 | """Base class for exceptions in this module."""
|
203 | 182 | pass
|
204 | 183 |
|
| 184 | + |
205 | 185 | class PN532:
|
206 | 186 | """PN532 driver base, must be extended for I2C/SPI/UART interfacing"""
|
207 | 187 |
|
@@ -464,167 +444,3 @@ def ntag2xx_read_block(self, block_number):
|
464 | 444 | not read then None will be returned.
|
465 | 445 | """
|
466 | 446 | return self.mifare_classic_read_block(block_number)[0:4] # only 4 bytes per page
|
467 |
| - |
468 |
| -class PN532_UART(PN532): |
469 |
| - """Driver for the PN532 connected over Serial UART""" |
470 |
| - def __init__(self, uart, *, irq=None, reset=None, debug=False): |
471 |
| - """Create an instance of the PN532 class using Serial connection. |
472 |
| - Optional IRQ pin (not used), reset pin and debugging output. |
473 |
| - """ |
474 |
| - self.debug = debug |
475 |
| - self._irq = irq |
476 |
| - self._uart = uart |
477 |
| - super().__init__(debug=debug, reset=reset) |
478 |
| - |
479 |
| - def _wakeup(self): |
480 |
| - """Send any special commands/data to wake up PN532""" |
481 |
| - #self._write_frame([_HOSTTOPN532, _COMMAND_SAMCONFIGURATION, 0x01]) |
482 |
| - self.SAM_configuration() |
483 |
| - |
484 |
| - def _wait_ready(self, timeout=1): |
485 |
| - """Wait `timeout` seconds""" |
486 |
| - time.sleep(timeout) |
487 |
| - return True |
488 |
| - |
489 |
| - def _read_data(self, count): |
490 |
| - """Read a specified count of bytes from the PN532.""" |
491 |
| - frame = self._uart.read(count) |
492 |
| - if not frame: |
493 |
| - raise BusyError("No data read from PN532") |
494 |
| - if self.debug: |
495 |
| - print("Reading: ", [hex(i) for i in frame]) |
496 |
| - else: |
497 |
| - time.sleep(0.1) |
498 |
| - return frame |
499 |
| - |
500 |
| - def _write_data(self, framebytes): |
501 |
| - """Write a specified count of bytes to the PN532""" |
502 |
| - while self._uart.read(1): # this would be a lot nicer if we could query the # of bytes |
503 |
| - pass |
504 |
| - self._uart.write('\x55\x55\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') # wake up! |
505 |
| - self._uart.write(framebytes) |
506 |
| - |
507 |
| -class PN532_I2C(PN532): |
508 |
| - """Driver for the PN532 connected over I2C.""" |
509 |
| - def __init__(self, i2c, *, irq=None, reset=None, req=None, debug=False): |
510 |
| - """Create an instance of the PN532 class using I2C. Note that PN532 |
511 |
| - uses clock stretching. Optional IRQ pin (not used), |
512 |
| - reset pin and debugging output. |
513 |
| - """ |
514 |
| - self.debug = debug |
515 |
| - self._irq = irq |
516 |
| - self._req = req |
517 |
| - if reset: |
518 |
| - _reset(reset) |
519 |
| - self._i2c = i2c_device.I2CDevice(i2c, _I2C_ADDRESS) |
520 |
| - super().__init__(debug=debug, reset=reset) |
521 |
| - |
522 |
| - def _wakeup(self): # pylint: disable=no-self-use |
523 |
| - """Send any special commands/data to wake up PN532""" |
524 |
| - if self._req: |
525 |
| - self._req.direction = Direction.OUTPUT |
526 |
| - self._req.value = True |
527 |
| - time.sleep(0.1) |
528 |
| - self._req.value = False |
529 |
| - time.sleep(0.1) |
530 |
| - self._req.value = True |
531 |
| - time.sleep(0.5) |
532 |
| - |
533 |
| - def _wait_ready(self, timeout=1): |
534 |
| - """Poll PN532 if status byte is ready, up to `timeout` seconds""" |
535 |
| - status = bytearray(1) |
536 |
| - timestamp = time.monotonic() |
537 |
| - while (time.monotonic() - timestamp) < timeout: |
538 |
| - try: |
539 |
| - with self._i2c: |
540 |
| - self._i2c.readinto(status) |
541 |
| - except OSError: |
542 |
| - self._wakeup() |
543 |
| - continue |
544 |
| - if status == b'\x01': |
545 |
| - return True # No longer busy |
546 |
| - else: |
547 |
| - time.sleep(0.05) # lets ask again soon! |
548 |
| - # Timed out! |
549 |
| - return False |
550 |
| - |
551 |
| - def _read_data(self, count): |
552 |
| - """Read a specified count of bytes from the PN532.""" |
553 |
| - # Build a read request frame. |
554 |
| - frame = bytearray(count+1) |
555 |
| - with self._i2c as i2c: |
556 |
| - i2c.readinto(frame, end=1) # read status byte! |
557 |
| - if frame[0] != 0x01: # not ready |
558 |
| - raise BusyError |
559 |
| - i2c.readinto(frame) # ok get the data, plus statusbyte |
560 |
| - if self.debug: |
561 |
| - print("Reading: ", [hex(i) for i in frame[1:]]) |
562 |
| - else: |
563 |
| - time.sleep(0.1) |
564 |
| - return frame[1:] # don't return the status byte |
565 |
| - |
566 |
| - def _write_data(self, framebytes): |
567 |
| - """Write a specified count of bytes to the PN532""" |
568 |
| - with self._i2c as i2c: |
569 |
| - i2c.write(framebytes) |
570 |
| - |
571 |
| -class PN532_SPI(PN532): |
572 |
| - """Driver for the PN532 connected over SPI. Pass in a hardware or bitbang |
573 |
| - SPI device & chip select digitalInOut pin. Optional IRQ pin (not used), |
574 |
| - reset pin and debugging output.""" |
575 |
| - def __init__(self, spi, cs_pin, *, irq=None, reset=None, debug=False): |
576 |
| - """Create an instance of the PN532 class using SPI""" |
577 |
| - self.debug = debug |
578 |
| - self._irq = irq |
579 |
| - self._spi = spi_device.SPIDevice(spi, cs_pin) |
580 |
| - super().__init__(debug=debug, reset=reset) |
581 |
| - |
582 |
| - def _wakeup(self): |
583 |
| - """Send any special commands/data to wake up PN532""" |
584 |
| - with self._spi as spi: |
585 |
| - time.sleep(1) |
586 |
| - spi.write(bytearray([0x00])) #pylint: disable=no-member |
587 |
| - time.sleep(1) |
588 |
| - |
589 |
| - def _wait_ready(self, timeout=1): |
590 |
| - """Poll PN532 if status byte is ready, up to `timeout` seconds""" |
591 |
| - status = bytearray([reverse_bit(_SPI_STATREAD), 0]) |
592 |
| - |
593 |
| - timestamp = time.monotonic() |
594 |
| - while (time.monotonic() - timestamp) < timeout: |
595 |
| - with self._spi as spi: |
596 |
| - time.sleep(0.02) # required |
597 |
| - spi.write_readinto(status, status) #pylint: disable=no-member |
598 |
| - if reverse_bit(status[1]) == 0x01: # LSB data is read in MSB |
599 |
| - return True # Not busy anymore! |
600 |
| - else: |
601 |
| - time.sleep(0.01) # pause a bit till we ask again |
602 |
| - # We timed out! |
603 |
| - return False |
604 |
| - |
605 |
| - def _read_data(self, count): |
606 |
| - """Read a specified count of bytes from the PN532.""" |
607 |
| - # Build a read request frame. |
608 |
| - frame = bytearray(count+1) |
609 |
| - # Add the SPI data read signal byte, but LSB'ify it |
610 |
| - frame[0] = reverse_bit(_SPI_DATAREAD) |
611 |
| - |
612 |
| - with self._spi as spi: |
613 |
| - time.sleep(0.02) # required |
614 |
| - spi.write_readinto(frame, frame) #pylint: disable=no-member |
615 |
| - for i, val in enumerate(frame): |
616 |
| - frame[i] = reverse_bit(val) # turn LSB data to MSB |
617 |
| - if self.debug: |
618 |
| - print("Reading: ", [hex(i) for i in frame[1:]]) |
619 |
| - return frame[1:] |
620 |
| - |
621 |
| - def _write_data(self, framebytes): |
622 |
| - """Write a specified count of bytes to the PN532""" |
623 |
| - # start by making a frame with data write in front, |
624 |
| - # then rest of bytes, and LSBify it |
625 |
| - rev_frame = [reverse_bit(x) for x in bytes([_SPI_DATAWRITE]) + framebytes] |
626 |
| - if self.debug: |
627 |
| - print("Writing: ", [hex(i) for i in rev_frame]) |
628 |
| - with self._spi as spi: |
629 |
| - time.sleep(0.02) # required |
630 |
| - spi.write(bytes(rev_frame)) #pylint: disable=no-member |
0 commit comments