Skip to content

Commit 2d8310f

Browse files
authored
Merge pull request #73 from jcerise/65/missing_type_annotations
Add type annotations
2 parents 7b81cf9 + b2cc3a4 commit 2d8310f

File tree

3 files changed

+78
-58
lines changed

3 files changed

+78
-58
lines changed

adafruit_rfm9x.py

Lines changed: 76 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@
2626
HAS_SUPERVISOR = True
2727
except ImportError:
2828
pass
29+
30+
try:
31+
from typing import Optional, Type, Literal
32+
from digitalio import DigitalInOut
33+
from busio import SPI
34+
from circuitpython_typing import WriteableBuffer, ReadableBuffer
35+
36+
except ImportError:
37+
pass
38+
2939
__version__ = "0.0.0-auto.0"
3040
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_RFM9x.git"
3141

@@ -120,7 +130,7 @@
120130
# pylint: disable=too-many-statements
121131

122132

123-
def ticks_diff(ticks1, ticks2):
133+
def ticks_diff(ticks1: int, ticks2: int) -> int:
124134
"""Compute the signed difference between two ticks values
125135
assuming that they are within 2**28 ticks
126136
"""
@@ -131,7 +141,7 @@ def ticks_diff(ticks1, ticks2):
131141

132142
class RFM9x:
133143
"""Interface to a RFM95/6/7/8 LoRa radio module. Allows sending and
134-
receivng bytes of data in long range LoRa mode at a support board frequency
144+
receiving bytes of data in long range LoRa mode at a support board frequency
135145
(433/915mhz).
136146
137147
You must specify the following parameters:
@@ -186,7 +196,7 @@ class _RegisterBits:
186196
# check from pylint.
187197
# pylint: disable=protected-access
188198

189-
def __init__(self, address, *, offset=0, bits=1):
199+
def __init__(self, address: int, *, offset: int = 0, bits: int = 1) -> None:
190200
assert 0 <= offset <= 7
191201
assert 1 <= bits <= 8
192202
assert (offset + bits) <= 8
@@ -198,11 +208,11 @@ def __init__(self, address, *, offset=0, bits=1):
198208
self._mask <<= offset
199209
self._offset = offset
200210

201-
def __get__(self, obj, objtype):
211+
def __get__(self, obj: "RFM9x", objtype: Type["RFM9x"]) -> int:
202212
reg_value = obj._read_u8(self._address)
203213
return (reg_value & self._mask) >> self._offset
204214

205-
def __set__(self, obj, val):
215+
def __set__(self, obj: "RFM9x", val: int) -> None:
206216
reg_value = obj._read_u8(self._address)
207217
reg_value &= ~self._mask
208218
reg_value |= (val & 0xFF) << self._offset
@@ -243,17 +253,17 @@ def __set__(self, obj, val):
243253

244254
def __init__(
245255
self,
246-
spi,
247-
cs,
248-
reset,
249-
frequency,
256+
spi: SPI,
257+
cs: DigitalInOut,
258+
reset: DigitalInOut,
259+
frequency: int,
250260
*,
251-
preamble_length=8,
252-
high_power=True,
253-
baudrate=5000000,
254-
agc=False,
255-
crc=True
256-
):
261+
preamble_length: int = 8,
262+
high_power: bool = True,
263+
baudrate: int = 5000000,
264+
agc: bool = False,
265+
crc: bool = True
266+
) -> None:
257267
self.high_power = high_power
258268
# Device support SPI mode 0 (polarity & phase = 0) up to a max of 10mhz.
259269
# Set Default Baudrate to 5MHz to avoid problems
@@ -363,7 +373,9 @@ def __init__(
363373

364374
# pylint: disable=no-member
365375
# Reconsider pylint: disable when this can be tested
366-
def _read_into(self, address, buf, length=None):
376+
def _read_into(
377+
self, address: int, buf: WriteableBuffer, length: Optional[int] = None
378+
) -> None:
367379
# Read a number of bytes from the specified address into the provided
368380
# buffer. If length is not specified (the default) the entire buffer
369381
# will be filled.
@@ -375,12 +387,14 @@ def _read_into(self, address, buf, length=None):
375387
device.write(self._BUFFER, end=1)
376388
device.readinto(buf, end=length)
377389

378-
def _read_u8(self, address):
390+
def _read_u8(self, address: int) -> int:
379391
# Read a single byte from the provided address and return it.
380392
self._read_into(address, self._BUFFER, length=1)
381393
return self._BUFFER[0]
382394

383-
def _write_from(self, address, buf, length=None):
395+
def _write_from(
396+
self, address: int, buf: ReadableBuffer, length: Optional[int] = None
397+
) -> None:
384398
# Write a number of bytes to the provided address and taken from the
385399
# provided buffer. If no length is specified (the default) the entire
386400
# buffer is written.
@@ -392,39 +406,40 @@ def _write_from(self, address, buf, length=None):
392406
device.write(self._BUFFER, end=1)
393407
device.write(buf, end=length)
394408

395-
def _write_u8(self, address, val):
409+
def _write_u8(self, address: int, val: int) -> None:
396410
# Write a byte register to the chip. Specify the 7-bit address and the
397411
# 8-bit value to write to that address.
398412
with self._device as device:
399-
self._BUFFER[0] = (address | 0x80) & 0xFF # Set top bit to 1 to
400-
# indicate a write.
413+
self._BUFFER[0] = (
414+
address | 0x80
415+
) & 0xFF # Set top bit to 1 to indicate a write.
401416
self._BUFFER[1] = val & 0xFF
402417
device.write(self._BUFFER, end=2)
403418

404-
def reset(self):
419+
def reset(self) -> None:
405420
"""Perform a reset of the chip."""
406421
# See section 7.2.2 of the datasheet for reset description.
407422
self._reset.value = False # Set Reset Low
408423
time.sleep(0.0001) # 100 us
409424
self._reset.value = True # set Reset High
410425
time.sleep(0.005) # 5 ms
411426

412-
def idle(self):
427+
def idle(self) -> None:
413428
"""Enter idle standby mode."""
414429
self.operation_mode = STANDBY_MODE
415430

416-
def sleep(self):
431+
def sleep(self) -> None:
417432
"""Enter sleep mode."""
418433
self.operation_mode = SLEEP_MODE
419434

420-
def listen(self):
435+
def listen(self) -> None:
421436
"""Listen for packets to be received by the chip. Use :py:func:`receive`
422437
to listen, wait and retrieve packets as they're available.
423438
"""
424439
self.operation_mode = RX_MODE
425440
self.dio0_mapping = 0b00 # Interrupt on rx done.
426441

427-
def transmit(self):
442+
def transmit(self) -> None:
428443
"""Transmit a packet which is queued in the FIFO. This is a low level
429444
function for entering transmit mode and more. For generating and
430445
transmitting a packet of data use :py:func:`send` instead.
@@ -433,7 +448,7 @@ def transmit(self):
433448
self.dio0_mapping = 0b01 # Interrupt on tx done.
434449

435450
@property
436-
def preamble_length(self):
451+
def preamble_length(self) -> int:
437452
"""The length of the preamble for sent and received packets, an unsigned
438453
16-bit value. Received packets must match this length or they are
439454
ignored! Set to 8 to match the RadioHead RFM95 library.
@@ -443,13 +458,13 @@ def preamble_length(self):
443458
return ((msb << 8) | lsb) & 0xFFFF
444459

445460
@preamble_length.setter
446-
def preamble_length(self, val):
461+
def preamble_length(self, val: int) -> None:
447462
assert 0 <= val <= 65535
448463
self._write_u8(_RH_RF95_REG_20_PREAMBLE_MSB, (val >> 8) & 0xFF)
449464
self._write_u8(_RH_RF95_REG_21_PREAMBLE_LSB, val & 0xFF)
450465

451466
@property
452-
def frequency_mhz(self):
467+
def frequency_mhz(self) -> Literal[433.0, 915.0]:
453468
"""The frequency of the radio in Megahertz. Only the allowed values for
454469
your radio must be specified (i.e. 433 vs. 915 mhz)!
455470
"""
@@ -461,7 +476,7 @@ def frequency_mhz(self):
461476
return frequency
462477

463478
@frequency_mhz.setter
464-
def frequency_mhz(self, val):
479+
def frequency_mhz(self, val: Literal[433.0, 915.0]) -> None:
465480
if val < 240 or val > 960:
466481
raise RuntimeError("frequency_mhz must be between 240 and 960")
467482
# Calculate FRF register 24-bit value.
@@ -475,7 +490,7 @@ def frequency_mhz(self, val):
475490
self._write_u8(_RH_RF95_REG_08_FRF_LSB, lsb)
476491

477492
@property
478-
def tx_power(self):
493+
def tx_power(self) -> int:
479494
"""The transmit power in dBm. Can be set to a value from 5 to 23 for
480495
high power devices (RFM95/96/97/98, high_power=True) or -1 to 14 for low
481496
power devices. Only integer power levels are actually set (i.e. 12.5
@@ -490,7 +505,7 @@ def tx_power(self):
490505
return self.output_power - 1
491506

492507
@tx_power.setter
493-
def tx_power(self, val):
508+
def tx_power(self, val: int) -> None:
494509
val = int(val)
495510
if self.high_power:
496511
if val < 5 or val > 23:
@@ -511,7 +526,7 @@ def tx_power(self, val):
511526
self.output_power = (val + 1) & 0x0F
512527

513528
@property
514-
def rssi(self):
529+
def rssi(self) -> int:
515530
"""The received strength indicator (in dBm) of the last received message."""
516531
# Read RSSI register and convert to value using formula in datasheet.
517532
# Remember in LoRa mode the payload register changes function to RSSI!
@@ -523,7 +538,7 @@ def rssi(self):
523538
return raw_rssi
524539

525540
@property
526-
def snr(self):
541+
def snr(self) -> float:
527542
"""The SNR (in dB) of the last received message."""
528543
# Read SNR 0x19 register and convert to value using formula in datasheet.
529544
# SNR(dB) = PacketSnr [twos complement] / 4
@@ -533,7 +548,7 @@ def snr(self):
533548
return snr_byte / 4
534549

535550
@property
536-
def signal_bandwidth(self):
551+
def signal_bandwidth(self) -> int:
537552
"""The signal bandwidth used by the radio (try setting to a higher
538553
value to increase throughput or to a lower value to increase the
539554
likelihood of successfully received payloads). Valid values are
@@ -546,7 +561,7 @@ def signal_bandwidth(self):
546561
return current_bandwidth
547562

548563
@signal_bandwidth.setter
549-
def signal_bandwidth(self, val):
564+
def signal_bandwidth(self, val: int) -> None:
550565
# Set signal bandwidth (set to 125000 to match RadioHead Bw125).
551566
for bw_id, cutoff in enumerate(self.bw_bins):
552567
if val <= cutoff:
@@ -581,7 +596,7 @@ def signal_bandwidth(self, val):
581596
self._write_u8(0x30, 0)
582597

583598
@property
584-
def coding_rate(self):
599+
def coding_rate(self) -> Literal[5, 6, 7, 8]:
585600
"""The coding rate used by the radio to control forward error
586601
correction (try setting to a higher value to increase tolerance of
587602
short bursts of interference or to a lower value to increase bit
@@ -591,7 +606,7 @@ def coding_rate(self):
591606
return denominator
592607

593608
@coding_rate.setter
594-
def coding_rate(self, val):
609+
def coding_rate(self, val: Literal[5, 6, 7, 8]) -> None:
595610
# Set coding rate (set to 5 to match RadioHead Cr45).
596611
denominator = min(max(val, 5), 8)
597612
cr_id = denominator - 4
@@ -601,7 +616,7 @@ def coding_rate(self, val):
601616
)
602617

603618
@property
604-
def spreading_factor(self):
619+
def spreading_factor(self) -> Literal[6, 7, 8, 9, 10, 11, 12]:
605620
"""The spreading factor used by the radio (try setting to a higher
606621
value to increase the receiver's ability to distinguish signal from
607622
noise or to a lower value to increase the data transmission rate).
@@ -610,7 +625,7 @@ def spreading_factor(self):
610625
return sf_id
611626

612627
@spreading_factor.setter
613-
def spreading_factor(self, val):
628+
def spreading_factor(self, val: Literal[6, 7, 8, 9, 10, 11, 12]) -> None:
614629
# Set spreading factor (set to 7 to match RadioHead Sf128).
615630
val = min(max(val, 6), 12)
616631

@@ -629,14 +644,14 @@ def spreading_factor(self, val):
629644
)
630645

631646
@property
632-
def enable_crc(self):
647+
def enable_crc(self) -> bool:
633648
"""Set to True to enable hardware CRC checking of incoming packets.
634649
Incoming packets that fail the CRC check are not processed. Set to
635650
False to disable CRC checking and process all incoming packets."""
636651
return (self._read_u8(_RH_RF95_REG_1E_MODEM_CONFIG2) & 0x04) == 0x04
637652

638653
@enable_crc.setter
639-
def enable_crc(self, val):
654+
def enable_crc(self, val: bool) -> None:
640655
# Optionally enable CRC checking on incoming packets.
641656
if val:
642657
self._write_u8(
@@ -649,29 +664,29 @@ def enable_crc(self, val):
649664
self._read_u8(_RH_RF95_REG_1E_MODEM_CONFIG2) & 0xFB,
650665
)
651666

652-
def tx_done(self):
667+
def tx_done(self) -> bool:
653668
"""Transmit status"""
654669
return (self._read_u8(_RH_RF95_REG_12_IRQ_FLAGS) & 0x8) >> 3
655670

656-
def rx_done(self):
671+
def rx_done(self) -> bool:
657672
"""Receive status"""
658673
return (self._read_u8(_RH_RF95_REG_12_IRQ_FLAGS) & 0x40) >> 6
659674

660-
def crc_error(self):
675+
def crc_error(self) -> bool:
661676
"""crc status"""
662677
return (self._read_u8(_RH_RF95_REG_12_IRQ_FLAGS) & 0x20) >> 5
663678

664679
# pylint: disable=too-many-branches
665680
def send(
666681
self,
667-
data,
682+
data: ReadableBuffer,
668683
*,
669-
keep_listening=False,
670-
destination=None,
671-
node=None,
672-
identifier=None,
673-
flags=None
674-
):
684+
keep_listening: bool = False,
685+
destination: Optional[int] = None,
686+
node: Optional[int] = None,
687+
identifier: Optional[int] = None,
688+
flags: Optional[int] = None
689+
) -> bool:
675690
"""Send a string of data using the transmitter.
676691
You can only send 252 bytes at a time
677692
(limited by chip's FIFO size and appended headers).
@@ -743,7 +758,7 @@ def send(
743758
self._write_u8(_RH_RF95_REG_12_IRQ_FLAGS, 0xFF)
744759
return not timed_out
745760

746-
def send_with_ack(self, data):
761+
def send_with_ack(self, data: ReadableBuffer) -> bool:
747762
"""Reliable Datagram mode:
748763
Send a packet with data and wait for an ACK response.
749764
The packet header is automatically generated.
@@ -781,15 +796,20 @@ def send_with_ack(self, data):
781796
return got_ack
782797

783798
def receive(
784-
self, *, keep_listening=True, with_header=False, with_ack=False, timeout=None
785-
):
799+
self,
800+
*,
801+
keep_listening: bool = True,
802+
with_header: bool = False,
803+
with_ack: bool = False,
804+
timeout: Optional[float] = None
805+
) -> Optional[bytearray]:
786806
"""Wait to receive a packet from the receiver. If a packet is found the payload bytes
787807
are returned, otherwise None is returned (which indicates the timeout elapsed with no
788808
reception).
789809
If keep_listening is True (the default) the chip will immediately enter listening mode
790810
after reception of a packet, otherwise it will fall back to idle mode and ignore any
791811
future reception.
792-
All packets must have a 4-byte header for compatibilty with the
812+
All packets must have a 4-byte header for compatibility with the
793813
RadioHead library.
794814
The header consists of 4 bytes (To,From,ID,Flags). The default setting will strip
795815
the header before returning the packet to the caller.

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
#
33
# SPDX-License-Identifier: Unlicense
44

5-
Adafruit-Blinka
5+
Adafruit-Blinka>=7.2.3
66
adafruit-circuitpython-busdevice

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
# Author details
3535
author="Adafruit Industries",
3636
author_email="[email protected]",
37-
install_requires=["Adafruit-Blinka", "adafruit-circuitpython-busdevice"],
37+
install_requires=["Adafruit-Blinka>=7.2.3", "adafruit-circuitpython-busdevice"],
3838
# Choose your license
3939
license="MIT",
4040
# See https://pypi.python.org/pypi?%3Aaction=list_classifiers

0 commit comments

Comments
 (0)