Tx/Rx Options#
RAIL provides some useful options when transmitting and receiving packets. In this document, we're going to cover those. Also, the Listen Before Talk as well as the Address Filtering features will be discussed in this article.
Tx Options#
The main Tx options should be passed to RAIL using the
RAIL_TxOptions_t
parameter of the RAIL_StartTx
APIs. The available options are practically
implemented as a bitmask type:
RAIL_TX_OPTION_WAIT_FOR_ACK
: Waits for ACK after transmitting a packet. I.e., the radio will automatically switch to Rx mode after Tx (disregarding auto state transitions) with a given timeout.RAIL_TX_OPTION_REMOVE_CRC
: Ignores the config's CRC setting and does not transmit CRC.RAIL_TX_OPTION_SYNC_WORD_ID
: If set, Tx will use the second configured sync word. If unset, it will use the first one.RAIL_TX_OPTION_ANTENNA0
: Uses antenna 0 (usually used when 2 antennas are available for antenna diversity).RAIL_TX_OPTION_ANTENNA1
: Uses antenna 1 (usually used when 2 antennas are available for antenna diversity).RAIL_TX_OPTION_ALT_PREAMBLE_LEN
: Uses an alternative preamble length configured by the RAIL_SetTxAltPreambleLength() API.RAIL_TX_OPTION_CCA_PEAK_RSSI
: Uses peak RSSI measurement in CCA instead of averaging (detailed later).RAIL_TX_OPTION_CCA_ONLY
: With this option the transmit after the CCA should be started manually (detailed later).RAIL_TX_OPTION_RESEND
: If the Tx FIFO has a single, complete packet in it, this option can be used the send it over on over without reloading the FIFO.RAIL_TX_OPTION_CONCURRENT_PHY_ID
: Selects the Tx PHY when concurrent mode is used in the Wi-SUN stack.
If both RAIL_TX_OPTION_ANTENNA0/1
option is not set, the active antenna will
be the one, which was selected by the last Tx/Rx operation.
RAIL_TX_OPTION_CCA_PEAK_RSSI
isn't supported on EFR32xG1 platforms.
The usual groups are also defined: RAIL_TX_OPTIONS_ALL
, RAIL_TX_OPTIONS_NONE
and RAIL_TX_OPTIONS_DEFAULT
(which is the same as RAIL_TX_OPTIONS_NONE
).
Rx Options#
Rx options can be configured using
RAIL_ConfigRxOptions(),
which takes two RAIL_RxOptions_t
parameter, mask
and options
. This way,
it's easy to change the options individually, without tweaking the rest. The
available options are:
RAIL_RX_OPTION_STORE_CRC
: By default, RAIL does not store the CRC, only checks it. By enabling this, it will store it as well. It can be used for example for sniffer applications.RAIL_RX_OPTION_IGNORE_CRC_ERRORS
: Frames will be received even if it failed CRC check. When enabled, the result of the CRC check will be stored in theRAIL_RxPacketDetails_t.crcPassed
field.RAIL_RX_OPTION_ENABLE_DUALSYNC
: Enables the detection of both sync word.RAIL_RX_OPTION_TRACK_ABORTED_FRAMES
: RAIL aborts frame reception when it filters it using the address filter. With this option enabled, it will receive the full frame (but still generates the correct error event) so the network analyzer can display it (through PTI).RAIL_RX_OPTION_REMOVE_APPENDED_INFO
: Disables the storage of the appended info. Appended info is used to store the base of RAIL_RxPacketDetails_t, like timestamp and RSSI. If not needed, it can be disabled, saving some buffer space.RAIL_RX_OPTION_ANTENNA0
: Uses antenna 0 (usually used when 2 antennas are available for antenna diversity).RAIL_RX_OPTION_ANTENNA1
: Uses antenna 1 (usually used when 2 antennas are available for antenna diversity).RAIL_RX_OPTION_ANTENNA_AUTO
: Uses both antennas, with antenna diversity (must be configured before using it).RAIL_RX_OPTION_DISABLE_FRAME_DETECTION
: Disables the frame detection system. Useful, if you only want to check the energy of a channel, and do not want to receive frames, because it would break the application's state machines.RAIL_RX_OPTION_CHANNEL_SWITCHING
: Enables concurrent listening on two IEEE 802.15.4 channels, with duty cycling. It requires a specially tuned radio config and only available on a few platforms.RAIL_RX_OPTION_FAST_RX2RX
: Speeds up returning to receive mode after finished (or aborted) receiving a packet. However, it will generate an Rx error event if packet reception is completed while the previous packet is still processing.RAIL_RX_OPTION_ENABLE_COLLISION_DETECTION
: Enables collision detection required by the Wi-SUN stack.
RAIL_RX_OPTION_IGNORE_CRC_ERRORS
affects also on ACK packets and Auto State
transition: packets with CRC error will be handled as successfully received
packets.
*RAIL_RX_OPTION_ENABLE_DUALSYNC
is not available for certain
combinations of chips, PHYs, and protocols. Also, it is not possible to listen
only for SYNC2.
RAIL_RX_OPTION_ANTENNA_AUTO
is not a unique value, it's actually
RAIL_RX_OPTION_ANTENNA0|RAIL_RX_OPTION_ANTENNA1
The usual groups are also defined: RAIL_RX_OPTIONS_ALL
, RAIL_RX_OPTIONS_NONE
and RAIL_RX_OPTIONS_DEFAULT
(which is the same as RAIL_RX_OPTIONS_NONE
).
Some options, like the antenna selections will restart receive mode (if changed in receive mode).
Listen Before Talk Options#
Listen before talk setups are often required in protocols, and a good idea to implement in some proprietary protocols as well. It solves most collisions between transmissions.
Listen before talk operations are built up from 3 tasks:
CCA (Clear Channel Assessment): the "listen" itself, where the radio is in Rx, measuring RSSI, and decides for or against transmission
Backoffs: randomized delays between CCA operations
Transmission: this is the 'talk' part, in which the radio sends the preconfigured packet
Measuring RSSI means averaging during a predefined period in most cases.
However, setting the RAIL_TX_OPTION_CCA_PEAK_RSSI
option makes it available to
use the peak instead of the mean RSSI value.
Generally, the radio starts with CCA: If the RSSI is below threshold, it starts transmitting. If not, it waits a random backoff period and tries CCA again. The radio should repeat this with increasing backoff periods, until successful transmission or timeout.
CCA period on EFR32 is derived from symbol time, so the minimum and maximum configurable values can differ from radio config to radio config.
The backoffs are implemented on the same timer that handles the scheduling, so it could cause problems if you start a listen before start operation from a scheduled Rx. Also, scheduled listen before talk Tx operations are not supported.
CSMA/CA#
The most common listen before talk protocol is CSMA/CA (Carrier-sense Multiple
Access with Collision Avoidance), which is fully supported by the EFR32
hardware. CSMA/CA defines backoffs as a random number with even distribution
between 0
and unit * (2^BE - 1)
, where BE
is the backoff exponent, which
increments with each retries.
To trigger a CSMA/CA transmission, you can start transmitting with
RAIL_StartCcaCsmaTx()
instead of RAIL_StartTx()
. The API has an extra argument, with the type of
RAIL_CsmaConfig_t,
that configures the CSMA/CA parameters:
csmaMinBoExp
andcsmaMaxBoExp
are setting the minimum and maximum backoff exponent (i.e., the first value ofBE
will becsmaMinBoExp
, andBE
increments up tocsmaMaxBoExp
).csmaTries
sets the number of tries (i.e., how many CCA should be performed before reporting back a busy channel).ccaThreshold
sets a threshold for comparing against the measured RSSI during the CCA; if the measured RSSI exceeds the threshold the channel will be judged busy.ccaBackoff
is the backoffunit
in μs.ccaDuration
sets the duration the CCA should take in μs (i.e., how long it should measure the RSSI).csmaTimeout
sets the timeout in μs: if the CSMA/CA operation exceeds this timeout it will stop. This is useful, since due to the random backoffs, the CSMA/CA duration can vary. Set it to0
to disable the timeout.
ccaBackoff
will be truncated if it is higher than 511. Setting csmaTries
to 0 will disable CSMA/CA: calling RAIL_StartCcaCsmaTx()
or RAIL_StartTx()
has the same result.
There's also a special setup: if csmaMinBoExp
and csmaMaxBoExp
are both set
to 0, that means a fixed backoff configuration. In this case, the backoff will
always take the time set in ccaBackoff
. With fixed backoff the ccaBackoff
won't be truncated.
LBT#
Another common listen before talk protocol is the obviously named LBT. It is defined in ETSI EN 300 220-1, under the Polite Spectrum Access chapter.
LBT defines backoffs as a unit * BO
, where BO
is a random number with even
distribution between a minimum and maximum.
LBT is not supported by the EFR32 hardware, it is converted to a CSMA/CA configuration in RAIL. Because of this, if you can choose between the two, you should choose CSMA/CA.
Note that LBT can be configured with a minimum backoff limit, while CSMA/CA's
minimum backoff period is always 0. This is not supported by the hardware, so
LBT is implemented with a bit of cheating. The CCA period is set to the
configured period + unit * minBO
. It doesn't really matter if the CCA period
is longer, and this guarantees that the minimum backoff is fulfilled.
Another limitation is that the maximum backoff must be power of 2, so the configured backoff will be rounded to the closest power of 2.
Much like CSMA/CA, LBT has its own StartTx
API,
RAIL_StartCcaLbtTx(),
which has a familiar config struct,
RAIL_LbtConfig_t to
configure the LBT parameters:
lbtMinBoRand
andlbtMaxBoRand
are setting the limits of the random backoff, just like with CSMA/CAlbtTries
sets the number of tries, similarly to CSMA/CAlbtBackoff
is the backoffunit
in μslbtThreshold
is a similar threshold what we've seen in CSMA/CAlbtDuration
sets the duration the CCA should take in μslbtTimeout
sets the same timeout as CSMA/CA
Setting lbtTries
to 0 will disable LBT, just like with CSMA/CA.
Custom Listen Before Talk#
A single CCA operation can be started using RAIL_TX_OPTION_CCA_ONLY
and with
csmaTries
set to 1. With this and software timers, a custom listen before talk
protocol can be implemented. Additionally, the RSSI API
(RAIL_GetRssi()
and
RAIL_StartAverageRSSI())
can be also used for similar purposes.
Address Filtering#
EFR32 supports hardware based address filtering, as long as the address is
stored in the same location in all the frames (unlike 802.15.4, which is only
supported through the protocol specific
API). EFR32 supports 2
address fields (e.g., for group and device address), both can be up to 8
Bytes long. Both fields can be configured for up to 4 addresses (e.g., for
broadcast, unicast and 2 multicast address). Any combination can be allowed on
these two fields, e.g., enable address1
for field0
only if field1
has
address1
, or if field0
has address2
, anything is allowed on field1
.
Enabling the address filter starts with configuring it, using:
RAIL_AddrConfig_t addrConfig = {
.offsets = {2, 0},
.sizes = {4, 0},
.matchTable = ADDRCONFIG_MATCH_TABLE_SINGLE_FIELD,
};
RAIL_ConfigAddressFilter(rail_handle, &addrConfig);
Its only parameter (apart from the usual rail_handle
) is RAIL_AddrConfig_t
.
RAIL_AddrConfig_t
configures:
offsets[(2)]
, which sets the offset of the addresses in the frame. For the first field, from the end of sync word; for the second field, from the end of the first field. Note that this means that the fields cannot overlap.sizes[(2)]
, which sets the size of the fields in byte. Setting it to 0 disables the field.matchTable
, which configures the enabled combinations of the fields.
If you only use a single field, you can safely use ADDRCONFIG_MATCH_TABLE_SINGLE_FIELD. If you need both address fields, you should understand how the match table works. That is out of the scope of this article, but you can rely on the API documentation.
Next, you load the addresses, using:
uint8_t address[4] = {0xAA, 0xBB, 0xCC, 0xDD};
RAIL_SetAddressFilterAddress(railHandle, 0, 1, address, true);
Which will enable the address 0xAABBCCDD on field 0, index 1, in enabled state. Make sure your address length matches what you configured for the field. You can later disable (and re-enable) it with:
RAIL_EnableAddressFilterAddress(railHandle, false, 0, 1);
Note that this API is referencing the address by its field and index. If you want to enable/disable addresses based on the value, i.e., the address itself, you should track which index is used for each address.
Finally, to enable (or disable) the whole address filter, use:
RAIL_EnableAddressFilter(railHandle, true);
Once address filter is enabled, you can get notifications on filtered frames using the RAIL_EVENT_RX_ADDRESS_FILTERED event.