diff --git a/adafruit_rfm9x.py b/adafruit_rfm9x.py index c09173e..915f90c 100644 --- a/adafruit_rfm9x.py +++ b/adafruit_rfm9x.py @@ -33,7 +33,7 @@ import digitalio from micropython import const -import adafruit_bus_device.spi_device as spi_device +import adafruit_bus_device.spi_device as spidev __version__ = "0.0.0-auto.0" @@ -338,8 +338,8 @@ def __init__(self, spi, cs, reset, frequency, *, preamble_length=8, self.high_power = high_power # Device support SPI mode 0 (polarity & phase = 0) up to a max of 10mhz. # Set Default Baudrate to 5MHz to avoid problems - self._device = spi_device.SPIDevice(spi, cs, baudrate=baudrate, - polarity=0, phase=0) + self._device = spidev.SPIDevice(spi, cs, baudrate=baudrate, + polarity=0, phase=0) # Setup reset as a digital input (default state for reset line according # to the datasheet). This line is pulled low as an output quickly to # trigger a reset. Note that reset MUST be done like this and set as @@ -533,11 +533,15 @@ def rssi(self): # Remember in LoRa mode the payload register changes function to RSSI! return self._read_u8(_RH_RF95_REG_1A_PKT_RSSI_VALUE) - 137 - def send(self, data, timeout=2.): - """Send a string of data using the transmitter. You can only send 252 - bytes at a time (limited by chip's FIFO size and appended headers). Note - this appends a 4 byte header to be compatible with the RadioHead library. - The timeout is just to prevent a hang (arbitrarily set to 2 Seconds). + def send(self, data, timeout=2., + tx_header=(_RH_BROADCAST_ADDRESS, _RH_BROADCAST_ADDRESS, 0, 0)): + """Send a string of data using the transmitter. + You can only send 252 bytes at a time + (limited by chip's FIFO size and appended headers). + This appends a 4 byte header to be compatible with the RadioHead library. + The tx_header defaults to using the Broadcast addresses. It may be overidden + by specifying a 4-tuple of bytes containing (To,From,ID,Flags) + The timeout is just to prevent a hang (arbitrarily set to 2 seconds) """ # Disable pylint warning to not use length as a check for zero. # This is a puzzling warning as the below code is clearly the most @@ -545,15 +549,16 @@ def send(self, data, timeout=2.): # buffer be within an expected range of bounds. Disable this check. # pylint: disable=len-as-condition assert 0 < len(data) <= 252 + assert len(tx_header) == 4, "tx header must be 4-tuple (To,From,ID,Flags)" # pylint: enable=len-as-condition self.idle() # Stop receiving to clear FIFO and keep it clear. # Fill the FIFO with a packet to send. self._write_u8(_RH_RF95_REG_0D_FIFO_ADDR_PTR, 0x00) # FIFO starts at 0. # Write header bytes. - self._write_u8(_RH_RF95_REG_00_FIFO, _RH_BROADCAST_ADDRESS) # txHeaderTo - self._write_u8(_RH_RF95_REG_00_FIFO, _RH_BROADCAST_ADDRESS) # txHeaderFrom - self._write_u8(_RH_RF95_REG_00_FIFO, 0x00) # txHeaderId - self._write_u8(_RH_RF95_REG_00_FIFO, 0x00) # txHeaderFlags + self._write_u8(_RH_RF95_REG_00_FIFO, tx_header[0]) # Header: To + self._write_u8(_RH_RF95_REG_00_FIFO, tx_header[1]) # Header: From + self._write_u8(_RH_RF95_REG_00_FIFO, tx_header[2]) # Header: Id + self._write_u8(_RH_RF95_REG_00_FIFO, tx_header[3]) # Header: Flags # Write payload. self._write_from(_RH_RF95_REG_00_FIFO, data) # Write payload and header length. @@ -574,16 +579,29 @@ def send(self, data, timeout=2.): if timed_out: raise RuntimeError('Timeout during packet send') - def receive(self, timeout=0.5, keep_listening=True): - """Wait to receive a packet from the receiver. Will wait for up to - timeout amount of seconds for a packet to be received and decoded. If - a packet is found the payload bytes are returned, otherwise None is - returned (which indicates the timeout elapsed with no reception). Note - this assumes a 4-byte header is prepended to the data for compatibilty - with the RadioHead library (the header is not validated nor returned). - If keep_listening is True (the default) the chip will immediately enter - listening mode after reception of a packet, otherwise it will fall back - to idle mode and ignore any future reception. + + + def receive(self, timeout=0.5, keep_listening=True, with_header=False, + rx_filter=_RH_BROADCAST_ADDRESS): + """Wait to receive a packet from the receiver. Will wait for up to timeout_s amount of + seconds for a packet to be received and decoded. If a packet is found the payload bytes + are returned, otherwise None is returned (which indicates the timeout elapsed with no + reception). + If keep_listening is True (the default) the chip will immediately enter listening mode + after reception of a packet, otherwise it will fall back to idle mode and ignore any + future reception. + A 4-byte header must be prepended to the data for compatibilty with the + RadioHead library. + The header consists of a 4 bytes (To,From,ID,Flags). The default setting will accept + any incomming packet and strip the header before returning the packet to the caller. + If with_header is True then the 4 byte header will be returned with the packet. + The payload then begins at packet[4]. + rx_fliter may be set to reject any "non-broadcast" packets that do not contain the + specfied "To" value in the header. + if rx_filter is set to 0xff (_RH_BROADCAST_ADDRESS) or if the "To" field (packet[[0]) + is equal to 0xff then the packet will be accepted and returned to the caller. + If rx_filter is not 0xff and packet[0] does not match rx_filter then + the packet is ignored and None is returned. """ # Make sure we are listening for packets. self.listen() @@ -612,7 +630,10 @@ def receive(self, timeout=0.5, keep_listening=True): packet = bytearray(length) # Read the packet. self._read_into(_RH_RF95_REG_00_FIFO, packet) - # strip off the header + if (rx_filter != _RH_BROADCAST_ADDRESS and packet[0] != _RH_BROADCAST_ADDRESS + and packet[0] != rx_filter): + packet = None + if not with_header: # skip the header if not wanted packet = packet[4:] # Listen again if necessary and return the result packet. if keep_listening: