|
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