Radio Control Layer (RCL)
NESB PRX Command Handler

Introduction

A PRX device normally acts as the main receiver in an NESB network. Depending on user configuration, the handler acts similarly to the Generic Rx Command handler, or it can add automatic acknowledgement and address filtering.

The following sections describe how the command can be configured and used, its life cycle, and how it fits into the RCL architecture.

Usage

In order to submit a PRX command, the following steps must have taken place:

  1. RCL has been initialized (See RCL_init) and a handle must exist (See RCL_open).
  2. The RCL_CMD_NESB_PRX_t command has been initialized and configured.
  3. A Multibuffer has been set up to receive the incoming packets.

Once these steps have been completed, RCL_Command_submit and RCL_Command_pend are called to effectively begin the RX operation, and then wait for the command to conclude.

Command configuration and submitting is similar to generic command handlers, but depending on the desired auto acknowledgment behavior, it might be necessary to also configure the sycnword specific behavior.

#define NUM_RX_BUF 1
#define MULTI_BUF_SZ 1024
void runNesbPrx(void)
{
uint32_t rxMultiBuffer[NUM_RX_BUF][MULTI_BUF_SZ / 4];
List_List multiBuffers = { 0 };
RCL_Handle h = RCL_open(&rclClient, &LRF_configNesb);
/* Declare command */
RCL_CmdNesbPrx cmd;
RCL_StatsNesb rxStats;
/* Command configuration */
cmd.common.scheduling = RCL_Schedule_AbsTime;
cmd.common.runtime.callback = defaultCallback;
cmd.common.runtime.rclCallbackMask.value = RCL_EventLastCmdDone.value | RCL_EventRxEntryAvail.value;
cmd.rfFrequency = FREQUENCY;
cmd.syncWordA = SYNCWORD;
cmd.syncWord[0].address = NESB_ADDR; // Set NESB address
cmd.addrLen = 4; // Consider 4 bytes for the NESB address
cmd.syncWord[0].seqValid = 1; // Only accept packets with sequence number and CRC different from the previous one
cmd.syncWord[0].autoAckMode = 3; // Enable auto-acknowledgement regardless of received NO_ACK.
/* Stats configuration */
rxStats.config.accumulate = 1;
rxStats.nTx = 0;
rxStats.nRxOk = 0;
rxStats.nRxNok = 0;
rxStats.nRxIgnored = 0;
rxStats.nRxAddrMismatch = 0;
rxStats.nRxBufFull = 0;
/* Set up Rx (multi)buffer */
for (int i = 0; i < NUM_RX_BUF; i++)
{
RCL_MultiBuffer *multiBuffer = (RCL_MultiBuffer *) rxMultiBuffer[i];
RCL_MultiBuffer_init(multiBuffer, MULTI_BUF_SZ);
RCL_MultiBuffer_put(&multiBuffers, multiBuffer);
}
/* Setup a graceful stop time */
uint32_t ticksPerByte = RCL_SCHEDULER_SYSTIM_US(8);
uint32_t startDelay = RCL_SCHEDULER_SYSTIM_US(6000000);
uint32_t endPktDelay = RCL_SCHEDULER_SYSTIM_US(150);
uint32_t packetOffset = ticksPerByte * 10 + endPktDelay;
uint32_t pktInterval = ticksPerByte * cmd.syncWord[0].maxPktLen + packetOffset;
cmd.common.timing.relGracefulStopTime = startDelay + NUM_PKT * pktInterval;
cmd.stats = &rxStats;
/* Clear multi buffers before starting */
RCL_MultiBuffer *multiBuffer = RCL_MultiBuffer_head(&multiBuffers);
while (multiBuffer != NULL)
{
RCL_MultiBuffer_clear(multiBuffer);
multiBuffer = RCL_MultiBuffer_next(multiBuffer);
}
cmd.rxBuffers = multiBuffers;
/* Configure the green LED pin */
GPIO_setConfig(CONFIG_GPIO_GLED, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
GPIO_write(CONFIG_GPIO_GLED, CONFIG_GPIO_LED_OFF);
/* Schedule command considering a start delay of 600 us */
cmd.common.timing.absStartTime = nextTime;
/* Wait for command to conclude */
/* Check the packet contents */
for (int i = 0; i < NUM_PKT; i++)
{
RCL_Buffer_DataEntry *rxPkt = RCL_MultiBuffer_RxEntry_get(&cmd.rxBuffers, NULL);
if (rxPkt != NULL)
{
/* Do something with the received packet */
}
}
}

Architecture

The NESB Prx command handler has a life cycle that depends on several things. If configuration is such that an acknowledgement is expected, the device will automatically switch from Rx mode to Tx mode to send an acknowledge to the specific PTX device that started the packet transaction. Furthermore, the PRX device performs address filtering so that it can ignore packets coming from PTX devices not associated with the network. If a valid packet from a valid address is received, the command can either continue listening for additional packets until a graceful or hard stop ends the operation. Once this has happened, the callback and the command status can be used for error checking and the application can proceed according to its specification.

NESB PRX handler state machine
RCL Event (In) Description
setup Setup has been performed
timerStart Timer-based start signalled
rxBufferUpdateRX buffer has been updated
RCL Event (Out) Description
lastCmdDone The RCL is finished with the command
cmdStarted Command handler has accepted and started executing
rxBufferFinished An RX multi-buffer is finished
rxEntryAvail An RX entry has been made available
LRF Event Description
opDone The PBE operation has finished
opError Something went wrong. Cause located in the PBE ENDCAUSE register
rxOk Packet received with CRC OK and not to be ignored by the MCU
rxNok Packet received with CRC error