|  | 
| 47 | 47 |   https://github.com/adafruit/circuitpython/releases | 
| 48 | 48 | * Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice | 
| 49 | 49 | """ | 
| 50 |  | -import time | 
| 51 | 50 | import random | 
| 52 |  | - | 
|  | 51 | +import time | 
|  | 52 | +import adafruit_bus_device.spi_device as spidev | 
| 53 | 53 | from micropython import const | 
| 54 | 54 | 
 | 
| 55 |  | -import adafruit_bus_device.spi_device as spidev | 
|  | 55 | +HAS_SUPERVISOR = False | 
|  | 56 | + | 
|  | 57 | +try: | 
|  | 58 | +    import supervisor | 
| 56 | 59 | 
 | 
|  | 60 | +    HAS_SUPERVISOR = hasattr(supervisor, "ticks_ms") | 
|  | 61 | +except ImportError: | 
|  | 62 | +    pass | 
| 57 | 63 | 
 | 
| 58 | 64 | __version__ = "0.0.0-auto.0" | 
| 59 | 65 | __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_RFM69.git" | 
|  | 
| 116 | 122 | FS_MODE = 0b010 | 
| 117 | 123 | TX_MODE = 0b011 | 
| 118 | 124 | RX_MODE = 0b100 | 
|  | 125 | +# supervisor.ticks_ms() contants | 
|  | 126 | +_TICKS_PERIOD = const(1 << 29) | 
|  | 127 | +_TICKS_MAX = const(_TICKS_PERIOD - 1) | 
|  | 128 | +_TICKS_HALFPERIOD = const(_TICKS_PERIOD // 2) | 
| 119 | 129 | 
 | 
| 120 | 130 | # Disable the silly too many instance members warning.  Pylint has no knowledge | 
| 121 | 131 | # of the context and is merely guessing at the proper amount of members.  This | 
|  | 
| 124 | 134 | # pylint: disable=too-many-instance-attributes | 
| 125 | 135 | 
 | 
| 126 | 136 | 
 | 
|  | 137 | +def ticks_diff(ticks1, ticks2): | 
|  | 138 | +    """Compute the signed difference between two ticks values | 
|  | 139 | +    assuming that they are within 2**28 ticks | 
|  | 140 | +    """ | 
|  | 141 | +    diff = (ticks1 - ticks2) & _TICKS_MAX | 
|  | 142 | +    diff = ((diff + _TICKS_HALFPERIOD) & _TICKS_MAX) - _TICKS_HALFPERIOD | 
|  | 143 | +    return diff | 
|  | 144 | + | 
|  | 145 | + | 
|  | 146 | +def check_timeout(flag, limit): | 
|  | 147 | +    """test for timeout waiting for specified flag""" | 
|  | 148 | +    timed_out = False | 
|  | 149 | +    if HAS_SUPERVISOR: | 
|  | 150 | +        start = supervisor.ticks_ms() | 
|  | 151 | +        while not timed_out and not flag(): | 
|  | 152 | +            if ticks_diff(supervisor.ticks_ms(), start) >= limit * 1000: | 
|  | 153 | +                timed_out = True | 
|  | 154 | +    else: | 
|  | 155 | +        start = time.monotonic() | 
|  | 156 | +        while not timed_out and not flag(): | 
|  | 157 | +            if time.monotonic() - start >= limit: | 
|  | 158 | +                timed_out = True | 
|  | 159 | +    return timed_out | 
|  | 160 | + | 
|  | 161 | + | 
| 127 | 162 | class RFM69: | 
| 128 | 163 |     """Interface to a RFM69 series packet radio.  Allows simple sending and | 
| 129 | 164 |     receiving of wireless data at supported frequencies of the radio | 
| @@ -474,10 +509,16 @@ def operation_mode(self, val): | 
| 474 | 509 |         op_mode |= val << 2 | 
| 475 | 510 |         self._write_u8(_REG_OP_MODE, op_mode) | 
| 476 | 511 |         # Wait for mode to change by polling interrupt bit. | 
| 477 |  | -        start = time.monotonic() | 
| 478 |  | -        while not self.mode_ready: | 
| 479 |  | -            if (time.monotonic() - start) >= 1: | 
| 480 |  | -                raise TimeoutError("Operation Mode failed to set.") | 
|  | 512 | +        if HAS_SUPERVISOR: | 
|  | 513 | +            start = supervisor.ticks_ms() | 
|  | 514 | +            while not self.mode_ready: | 
|  | 515 | +                if ticks_diff(supervisor.ticks_ms(), start) >= 1000: | 
|  | 516 | +                    raise TimeoutError("Operation Mode failed to set.") | 
|  | 517 | +        else: | 
|  | 518 | +            start = time.monotonic() | 
|  | 519 | +            while not self.mode_ready: | 
|  | 520 | +                if time.monotonic() - start >= 1: | 
|  | 521 | +                    raise TimeoutError("Operation Mode failed to set.") | 
| 481 | 522 | 
 | 
| 482 | 523 |     @property | 
| 483 | 524 |     def sync_word(self): | 
| @@ -693,6 +734,7 @@ def payload_ready(self): | 
| 693 | 734 |         """Receive status""" | 
| 694 | 735 |         return (self._read_u8(_REG_IRQ_FLAGS2) & 0x4) >> 2 | 
| 695 | 736 | 
 | 
|  | 737 | +    # pylint: disable=too-many-branches | 
| 696 | 738 |     def send( | 
| 697 | 739 |         self, | 
| 698 | 740 |         data, | 
| @@ -751,11 +793,7 @@ def send( | 
| 751 | 793 |         self.transmit() | 
| 752 | 794 |         # Wait for packet sent interrupt with explicit polling (not ideal but | 
| 753 | 795 |         # best that can be done right now without interrupts). | 
| 754 |  | -        start = time.monotonic() | 
| 755 |  | -        timed_out = False | 
| 756 |  | -        while not timed_out and not self.packet_sent(): | 
| 757 |  | -            if (time.monotonic() - start) >= self.xmit_timeout: | 
| 758 |  | -                timed_out = True | 
|  | 796 | +        timed_out = check_timeout(self.packet_sent, self.xmit_timeout) | 
| 759 | 797 |         # Listen again if requested. | 
| 760 | 798 |         if keep_listening: | 
| 761 | 799 |             self.listen() | 
| @@ -800,7 +838,6 @@ def send_with_ack(self, data): | 
| 800 | 838 |         self.flags = 0  # clear flags | 
| 801 | 839 |         return got_ack | 
| 802 | 840 | 
 | 
| 803 |  | -    # pylint: disable=too-many-branches | 
| 804 | 841 |     def receive( | 
| 805 | 842 |         self, *, keep_listening=True, with_ack=False, timeout=None, with_header=False | 
| 806 | 843 |     ): | 
| @@ -828,11 +865,7 @@ def receive( | 
| 828 | 865 |             # interrupt supports. | 
| 829 | 866 |             # Make sure we are listening for packets. | 
| 830 | 867 |             self.listen() | 
| 831 |  | -            start = time.monotonic() | 
| 832 |  | -            timed_out = False | 
| 833 |  | -            while not timed_out and not self.payload_ready(): | 
| 834 |  | -                if (time.monotonic() - start) >= timeout: | 
| 835 |  | -                    timed_out = True | 
|  | 868 | +            timed_out = check_timeout(self.payload_ready, timeout) | 
| 836 | 869 |         # Payload ready is set, a packet is in the FIFO. | 
| 837 | 870 |         packet = None | 
| 838 | 871 |         # save last RSSI reading | 
|  | 
0 commit comments