Skip to content

Add access to RadioHead header #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 25, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 44 additions & 23 deletions adafruit_rfm9x.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -533,27 +533,32 @@ 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
# efficient and proper way to ensure a precondition that the provided
# 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.
Expand All @@ -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()
Expand Down Expand Up @@ -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:
Expand Down