Other Parts Discussed in Thread: CC2340R5, UNIFLASH
Hi, Sir,
I have two CC2340R5 EVB and want to use the NESB command to implement the RF packet TX/RX. I check your example code in "nesb_ptx_handler.html" and "nesb_prx_handler.html" and fail to achieve it.
When I set the "cmd.config.autoRetransmitMode = 0" I can use the "rfPlacketRx" to receive the NESB TX but fail on NESB RX sample code. Can you help me check it ?
EVB version: RevB/PG2.0
CCS: 12.3.0.00005.
Sample code: rfPacketTx, rfPacketRx
Uniflash version: 8.3.0.4307
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.18"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Radio Control Layer (RCL): NESB PTX Command Handler</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="doxygen-awesome.css" rel="stylesheet" type="text/css"/>
<link href="doxygen-awesome-sidebar-only.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">Radio Control Layer (RCL)
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.18 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function(){initNavTree('nesb_ptx_handler.html',''); initResizable(); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div class="PageDoc"><div class="header">
<div class="headertitle">
<div class="title">NESB PTX Command Handler </div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h1><a class="anchor" id="autotoc_md44"></a>
Introduction</h1>
<p>A PTX device normally acts as the main transmitter in an NESB network. Depending on user configuration, the handler acts similarly to the Generic Tx Command handler, or it can add automatic retransmission of unacknowledged packets.</p>
<p>The following sections describe how the command can be configured and used, its life cycle, and how it fits into the <a class="el" href="_r_c_l_8h.html#struct_r_c_l" title="Global shared driver state.">RCL</a> architecture.</p>
<h1><a class="anchor" id="autotoc_md45"></a>
Usage</h1>
<p>In order to submit a PTX command, the following steps must have taken place:</p>
<ol type="1">
<li><a class="el" href="_r_c_l_8h.html#struct_r_c_l" title="Global shared driver state.">RCL</a> has been initialized (See <a class="el" href="_r_c_l_8h.html#a2fa1415c07a809621287abfc9b7f40f7" title="Initializes the RCL driver state.">RCL_init</a>) and a handle must exist (See <a class="el" href="_r_c_l_8h.html#ad250dbda0747820e489d38cdb268ecee" title="Initializes an RCL client instance.">RCL_open</a>).</li>
<li>The <a class="el" href="commands_2generic_8h.html#struct_r_c_l___c_m_d___n_e_s_b___p_t_x__t" title="NESB transmit command.">RCL_CMD_NESB_PTX_t</a> command has been initialized and configured.</li>
<li>The Tx buffer has been set up.</li>
<li>An RX buffer has been set up to receive the ACK (if configuration demands it).</li>
</ol>
<p>Once these steps have been completed, <a class="el" href="_r_c_l_8h.html#a335ebd06e9591a1a9ec26bde80199d96" title="Submit RCL command object to be scheduled for execution.">RCL_Command_submit</a> and <a class="el" href="_r_c_l_8h.html#adc809f6096147ac6e33641fb2161a859" title="Wait for a submitted command to complete.">RCL_Command_pend</a> are called to effectively send a packet and then wait for the command to conclude.</p>
<p>As with any command handler, the application must built packets so that they are compatible with the internal packet format used in the LRF. Having said this, NESB packets also have a specific packet format that needs to be considered at the application level.</p>
<p>This can be accomplished by using a struct to define the various fields that need to be considered when building or checking the content of the packet.</p>
<div class="fragment"><div class="line"><span class="preprocessor">#define PKT_LEN 200</span></div>
<div class="line"><span class="preprocessor">#define HDR_LEN 3</span></div>
<div class="line"><span class="preprocessor">#define NUM_PKT 4</span></div>
<div class="line"><span class="preprocessor">#define NUM_PAD 3</span></div>
<div class="line"><span class="preprocessor">#define NUM_RX_BUF 1</span></div>
<div class="line"><span class="preprocessor">#define MULTI_BUF_SZ 2048</span></div>
<div class="line"><span class="preprocessor">#define FREQUENCY 2470000000</span></div>
<div class="line"><span class="preprocessor">#define SYNCWORD 0xAB0B51DE</span></div>
<div class="line"><span class="preprocessor">#define NESB_ADDR 0xAC9825CB</span></div>
<div class="line"> </div>
<div class="line"><span class="preprocessor">#define NESB_hdrDef_Default() \</span></div>
<div class="line"><span class="preprocessor">{ \</span></div>
<div class="line"><span class="preprocessor"> .numHdrBits = 11, \</span></div>
<div class="line"><span class="preprocessor"> .numLenBits = 8, \</span></div>
<div class="line"><span class="preprocessor"> .lenPos = 3, \</span></div>
<div class="line"><span class="preprocessor"> .lenOffset = 0, \</span></div>
<div class="line"><span class="preprocessor"> .numPad = 3, \</span></div>
<div class="line"><span class="preprocessor">}</span></div>
<div class="line"><span class="preprocessor">#define NESB_hdrDef_DefaultRuntime() (ExampleRCL_NesbHdrDef) NESB_hdrDef_Default()</span></div>
<div class="line"> </div>
<div class="line"><span class="keyword">typedef</span> <span class="keyword">struct </span>{</div>
<div class="line"> uint8_t numHdrBits;</div>
<div class="line"> uint8_t numLenBits;</div>
<div class="line"> uint8_t lenPos;</div>
<div class="line"> int8_t lenOffset;</div>
<div class="line"> uint8_t numPad;</div>
<div class="line">} ExampleRCL_NesbHdrDef;</div>
</div><!-- fragment --><p> Taking this into consideration, packet generation needs to consider how the 11-bit header is placed in the LRF FIFO. the following function shows one way to accomplish this:</p>
<div class="fragment"><div class="line"><span class="keywordtype">void</span> generatePackets(RCL_Buffer_TxBuffer **txBuffers, uint32_t numPkt, uint32_t pktLen,</div>
<div class="line"> ExampleRCL_NesbHdrDef *hdrDef, uint32_t address, uint32_t addressLen)</div>
<div class="line">{</div>
<div class="line"> <span class="keyword">union</span></div>
<div class="line"> {</div>
<div class="line"> uint32_t value;</div>
<div class="line"> uint8_t bytes[4];</div>
<div class="line"> } nesbAddress;</div>
<div class="line"> <span class="keyword">union</span></div>
<div class="line"> {</div>
<div class="line"> uint16_t value;</div>
<div class="line"> uint8_t bytes[2];</div>
<div class="line"> } nesbHeader;</div>
<div class="line"> </div>
<div class="line"> uint8_t hdrLen = (hdrDef->numHdrBits + 7) / 8;</div>
<div class="line"> uint8_t seqNum = 0; <span class="comment">// Start with a seq number equal to zero</span></div>
<div class="line"> uint8_t noAckBit = 0; <span class="comment">// Always set the noAckBit to zero</span></div>
<div class="line"> nesbAddress.value = address;</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < numPkt; i++)</div>
<div class="line"> {</div>
<div class="line"> uint8_t *txData;</div>
<div class="line"> </div>
<div class="line"> <span class="comment">/* Initialize Tx Buffer */</span></div>
<div class="line"> txData = <a class="code" href="group__buffer_api_functions.html#ga6fc3e5a4bff33ded64a77ea203128805">RCL_TxBuffer_init</a>(txBuffers[i], hdrDef->numPad, hdrLen, pktLen);</div>
<div class="line"> </div>
<div class="line"> <span class="comment">/* Build the 11 bit NESB header */</span></div>
<div class="line"> nesbHeader.value = ((pktLen << 3) | (seqNum << 1) | noAckBit);</div>
<div class="line"> </div>
<div class="line"> <span class="comment">/* Write NESB header to buffer */</span></div>
<div class="line"> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < hdrLen; i++)</div>
<div class="line"> {</div>
<div class="line"> txData[i] = nesbHeader.bytes[i];</div>
<div class="line"> }</div>
<div class="line"> <span class="comment">/* Write NESB address to buffer. Address comes immediately after header */</span></div>
<div class="line"> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < addressLen; i++)</div>
<div class="line"> {</div>
<div class="line"> txData[hdrLen + i] = nesbAddress.bytes[i];</div>
<div class="line"> }</div>
<div class="line"> <span class="comment">/* Write the payload */</span></div>
<div class="line"> <span class="keywordflow">if</span>(pktLen >= addressLen)</div>
<div class="line"> {</div>
<div class="line"> uint32_t payloadLength = pktLen - addressLen;</div>
<div class="line"> <span class="keywordflow">for</span>(uint32_t i = 0; i < payloadLength; i++)</div>
<div class="line"> {</div>
<div class="line"> txData[hdrLen + addressLen + i] = i & 0xFF;</div>
<div class="line"> }</div>
<div class="line"> }</div>
<div class="line"> <span class="comment">/* Update packet ID (seq number) for next packet */</span></div>
<div class="line"> seqNum = (seqNum + 1) % 4;</div>
<div class="line"> }</div>
<div class="line">}</div>
</div><!-- fragment --><p> Command configuration and submitting is similar to generic command handlers.</p>
<div class="fragment"><div class="line"><span class="keywordtype">void</span> runNesbPtx(<span class="keywordtype">void</span>)</div>
<div class="line">{</div>
<div class="line"> ExampleRCL_NesbHdrDef hdrDef = NESB_hdrDef_DefaultRuntime();</div>
<div class="line"> List_List multiBuffers = { 0 };</div>
<div class="line"> uint32_t address = NESB_ADDR;</div>
<div class="line"> uint32_t addressLen = 4;</div>
<div class="line"> </div>
<div class="line"> <span class="comment">/* Set up Tx and Rx buffers considering 4 packets, packet length of 200 bytes, 2 header bytes and 3 padding bytes */</span></div>
<div class="line"> RCL_Buffer_TxBuffer *txBuffers[NUM_PKT];</div>
<div class="line"> uint32_t pktBuffer[NUM_PKT][<a class="code" href="group__buffer_api_functions.html#gade3c0fd0ae25d389875981dac43d5f15">RCL_TxBuffer_len_u32</a>(NUM_PAD, HDR_LEN, PKT_LEN)];</div>
<div class="line"> uint32_t rxMultiBuffer[NUM_RX_BUF][MULTI_BUF_SZ / 4];</div>
<div class="line"> </div>
<div class="line"> <a class="code" href="_r_c_l_8c.html#a145b90e0682b0e3fd914772879861e44">RCL_init</a>();</div>
<div class="line"> RCL_Handle h = <a class="code" href="_r_c_l_8c.html#ad250dbda0747820e489d38cdb268ecee">RCL_open</a>(&rclClient, &LRF_configNesb);</div>
<div class="line"> </div>
<div class="line"> <span class="comment">/* Declare command */</span></div>
<div class="line"> RCL_CmdNesbPtx cmd;</div>
<div class="line"> cmd = <a class="code" href="commands_2generic_8h.html#abf346875f81c8e9bbe0371a3e6cf9433">RCL_CmdNesbPtx_DefaultRuntime</a>();</div>
<div class="line"> </div>
<div class="line"> <span class="comment">/* Command configuration */</span></div>
<div class="line"> cmd.common.scheduling = <a class="code" href="_r_c_l___command_8h.html#ade08c929505da062070474163417817da36e4eb855b1a8b435564f5911266a55b">RCL_Schedule_AbsTime</a>;</div>
<div class="line"> cmd.common.runtime.callback = defaultCallback;</div>
<div class="line"> cmd.common.runtime.rclCallbackMask.value = <a class="code" href="_r_c_l___event_8h.html#a9e6384116d9e2d84f36990827d6e86f1">RCL_EventLastCmdDone</a>.value | <a class="code" href="_r_c_l___event_8h.html#a27efe993ce19cd501e8aadb7c5fa4aee">RCL_EventRxEntryAvail</a>.value;</div>
<div class="line"> cmd.rfFrequency = FREQUENCY;</div>
<div class="line"> cmd.syncWord = SYNCWORD;</div>
<div class="line"> cmd.config.hdrConf = 1; <span class="comment">// Insert SEQ and NO_ACK from Tx buffer</span></div>
<div class="line"> cmd.config.autoRetransmitMode = 3; <span class="comment">// Always listen for ACK and retransmit if missing.</span></div>
<div class="line"> cmd.maxRetrans = 5; <span class="comment">// Attempt 5 retransmissions if ACK is not received.</span></div>
<div class="line"> cmd.retransDelay = 50000; <span class="comment">// Wait 50000 Systim ticks (i.e. 12.5 ms) between retransmissions.</span></div>
<div class="line"> cmd.common.status = <a class="code" href="_r_c_l___command_8h.html#ae591a974abf55ca701cf33c61554e0cda1097a97f59467483fb55c8b471cb3036">RCL_CommandStatus_Idle</a>;</div>
<div class="line"> </div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < NUM_PKT; i++)</div>
<div class="line"> {</div>
<div class="line"> txBuffers[i] = (RCL_Buffer_TxBuffer *)pktBuffer[i];</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="comment">/* Set up Rx buffer to receive ACK packets */</span></div>
<div class="line"> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < NUM_RX_BUF; i++)</div>
<div class="line"> {</div>
<div class="line"> RCL_MultiBuffer *multiBuffer = (RCL_MultiBuffer *)rxMultiBuffer[i];</div>
<div class="line"> <a class="code" href="group__buffer_api_functions.html#ga9557389c0630c4bf6284036587279945">RCL_MultiBuffer_init</a>(multiBuffer, MULTI_BUF_SZ);</div>
<div class="line"> <a class="code" href="group__buffer_api_functions.html#gaf9be361ce2825a10f9ee8a132f8ad920">RCL_MultiBuffer_put</a>(&multiBuffers, multiBuffer);</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="comment">/* Clear multibuffer before starting the operation */</span></div>
<div class="line"> RCL_MultiBuffer *multiBuffer = <a class="code" href="group__buffer_api_functions.html#gaf48f36094b2839027feea9b2ed3db023">RCL_MultiBuffer_head</a>(&multiBuffers);</div>
<div class="line"> <span class="keywordflow">while</span> (multiBuffer != NULL)</div>
<div class="line"> {</div>
<div class="line"> <a class="code" href="group__buffer_api_functions.html#gabbbf7364e16aae6951ee7c827de9bf06">RCL_MultiBuffer_clear</a>(multiBuffer);</div>
<div class="line"> multiBuffer = <a class="code" href="group__buffer_api_functions.html#ga05fa5798eb559b09a069b15bad0de4f1">RCL_MultiBuffer_next</a>(multiBuffer);</div>
<div class="line"> }</div>
<div class="line"> cmd.rxBuffers = multiBuffers;</div>
<div class="line"> </div>
<div class="line"> <span class="comment">/* Generate the packets that will be sent and fill Tx buffer */</span></div>
<div class="line"> generatePackets(txBuffers, NUM_PKT, PKT_LEN, &hdrDef, address, addressLen);</div>
<div class="line"> <span class="keywordflow">for</span>(<span class="keywordtype">int</span> i = 0; i < NUM_PKT; i++)</div>
<div class="line"> {</div>
<div class="line"> <a class="code" href="group__buffer_api_functions.html#ga7ef1355f9f5e5afb2e301ab8554b4239">RCL_TxBuffer_put</a>(&cmd.txBuffers, txBuffers[i]);</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="comment">/* Schedule first command considering a start delay of 600 us */</span></div>
<div class="line"> uint32_t nextTime = <a class="code" href="group__timing_api_functions.html#gadf6e67c88e75cbe44f52b5b93eecdd09">RCL_Scheduler_getCurrentTime</a>() + <a class="code" href="_r_c_l___scheduler_8h.html#acdfb6b54cdc9e000704111729a8319a7">RCL_SCHEDULER_SYSTIM_US</a>(600);</div>
<div class="line"> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < NUM_PKT; i++)</div>
<div class="line"> {</div>
<div class="line"> cmd.common.status = <a class="code" href="_r_c_l___command_8h.html#ae591a974abf55ca701cf33c61554e0cda1097a97f59467483fb55c8b471cb3036">RCL_CommandStatus_Idle</a>;</div>
<div class="line"> cmd.common.timing.absStartTime = nextTime;</div>
<div class="line"> </div>
<div class="line"> <a class="code" href="_r_c_l_8c.html#a335ebd06e9591a1a9ec26bde80199d96">RCL_Command_submit</a>(h, &cmd);</div>
<div class="line"> <span class="comment">/* Wait for command to conclude */</span></div>
<div class="line"> <a class="code" href="_r_c_l_8c.html#adc809f6096147ac6e33641fb2161a859">RCL_Command_pend</a>(&cmd);</div>
<div class="line"> </div>
<div class="line"> <span class="comment">/* Schedule next command considering the same start delay */</span></div>
<div class="line"> nextTime = <a class="code" href="group__timing_api_functions.html#gadf6e67c88e75cbe44f52b5b93eecdd09">RCL_Scheduler_getCurrentTime</a>() + <a class="code" href="_r_c_l___scheduler_8h.html#acdfb6b54cdc9e000704111729a8319a7">RCL_SCHEDULER_SYSTIM_US</a>(600);</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="comment">/* Check ACK packets */</span></div>
<div class="line"> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < NUM_PKT; i++)</div>
<div class="line"> {</div>
<div class="line"> RCL_Buffer_DataEntry *rxPkt = <a class="code" href="group__buffer_api_functions.html#ga34d0923dddc433082c4d673e7331772d">RCL_MultiBuffer_RxEntry_get</a>(&cmd.rxBuffers, NULL);</div>
<div class="line"> <span class="keywordflow">if</span> (rxPkt != NULL)</div>
<div class="line"> {</div>
<div class="line"> <span class="comment">/* Do something with the received ACK */</span></div>
<div class="line"> }</div>
<div class="line"> }</div>
<div class="line">}</div>
</div><!-- fragment --> <h1><a class="anchor" id="autotoc_md46"></a>
Architecture</h1>
<p>The NESB Ptx 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 Tx mode to Rx mode to listen for an acknowledge coming from an associated PRX device in the network. Furthermore, if retransmission of unacknowledged packets is enabled, the PTX command handler will automatically switch back and forth between Tx mode and Rx mode in order to retransmit the packet. This will go on for a user-defined number of times and with a user-defined retransmission delay. If a valid acknowledgement is received, or if a packet is transmitted and no acknowledgement is expected, the command will conclude not before incrementing a sequence number that is used by the PRX device to differentiate between new packets and retransmitted packets.</p>
<p>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.</p>
<div class="plantumlgraph">
<img src="inline_umlgraph_10.png" />
<div class="caption">
NESB PTX handler state machine</div>
</div>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone"><a class="el" href="_r_c_l_8h.html#struct_r_c_l" title="Global shared driver state.">RCL</a> Event (In) </th><th class="markdownTableHeadNone">Description </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone"><em>setup</em> </td><td class="markdownTableBodyNone">Setup has been performed </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone"><em>timerStart</em> </td><td class="markdownTableBodyNone">Timer-based start signalled </td></tr>
</table>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone"><a class="el" href="_r_c_l_8h.html#struct_r_c_l" title="Global shared driver state.">RCL</a> Event (Out) </th><th class="markdownTableHeadNone">Description </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone"><em>lastCmdDone</em> </td><td class="markdownTableBodyNone">The <a class="el" href="_r_c_l_8h.html#struct_r_c_l" title="Global shared driver state.">RCL</a> is finished with the command </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone"><em>cmdStarted</em> </td><td class="markdownTableBodyNone">Command handler has accepted and started executing </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone"><em>rxBufferFinished</em> </td><td class="markdownTableBodyNone">An RX multi-buffer is finished </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone"><em>rxEntryAvail</em> </td><td class="markdownTableBodyNone">An RX entry has been made available </td></tr>
</table>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">LRF Event </th><th class="markdownTableHeadNone">Description </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone"><em>opDone</em> </td><td class="markdownTableBodyNone">The PBE operation has finished </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone"><em>opError</em> </td><td class="markdownTableBodyNone">Something went wrong. Cause located in the PBE ENDCAUSE register </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone"><em>rxOk</em> </td><td class="markdownTableBodyNone">Packet received with CRC OK and not to be ignored by the MCU </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone"><em>rxNok</em> </td><td class="markdownTableBodyNone">Packet received with CRC error </td></tr>
</table>
</div></div><!-- contents -->
</div><!-- PageDoc -->
</div><!-- doc-content -->
<div class="ttc" id="agroup__buffer_api_functions_html_ga7ef1355f9f5e5afb2e301ab8554b4239"><div class="ttname"><a href="group__buffer_api_functions.html#ga7ef1355f9f5e5afb2e301ab8554b4239">RCL_TxBuffer_put</a></div><div class="ttdeci">void RCL_TxBuffer_put(List_List *list, RCL_Buffer_TxBuffer *elem)</div><div class="ttdoc">Function to atomically put an elem onto the end of a Tx Buffer list.</div><div class="ttdef"><b>Definition:</b> RCL_Buffer.c:58</div></div>
<div class="ttc" id="a_r_c_l_8c_html_adc809f6096147ac6e33641fb2161a859"><div class="ttname"><a href="_r_c_l_8c.html#adc809f6096147ac6e33641fb2161a859">RCL_Command_pend</a></div><div class="ttdeci">RCL_CommandStatus RCL_Command_pend(RCL_Command_Handle c)</div><div class="ttdoc">Wait for a submitted command to complete.</div><div class="ttdef"><b>Definition:</b> RCL.c:667</div></div>
<div class="ttc" id="a_r_c_l_8c_html_ad250dbda0747820e489d38cdb268ecee"><div class="ttname"><a href="_r_c_l_8c.html#ad250dbda0747820e489d38cdb268ecee">RCL_open</a></div><div class="ttdeci">RCL_Handle RCL_open(RCL_Client *c, const LRF_Config *lrfConfig)</div><div class="ttdoc">Initializes an RCL client instance.</div><div class="ttdef"><b>Definition:</b> RCL.c:554</div></div>
<div class="ttc" id="a_r_c_l___scheduler_8h_html_acdfb6b54cdc9e000704111729a8319a7"><div class="ttname"><a href="_r_c_l___scheduler_8h.html#acdfb6b54cdc9e000704111729a8319a7">RCL_SCHEDULER_SYSTIM_US</a></div><div class="ttdeci">#define RCL_SCHEDULER_SYSTIM_US(x)</div><div class="ttdef"><b>Definition:</b> RCL_Scheduler.h:45</div></div>
<div class="ttc" id="a_r_c_l_8c_html_a335ebd06e9591a1a9ec26bde80199d96"><div class="ttname"><a href="_r_c_l_8c.html#a335ebd06e9591a1a9ec26bde80199d96">RCL_Command_submit</a></div><div class="ttdeci">RCL_CommandStatus RCL_Command_submit(RCL_Handle h, RCL_Command_Handle c)</div><div class="ttdoc">Submit RCL command object to be scheduled for execution.</div><div class="ttdef"><b>Definition:</b> RCL.c:633</div></div>
<div class="ttc" id="agroup__timing_api_functions_html_gadf6e67c88e75cbe44f52b5b93eecdd09"><div class="ttname"><a href="group__timing_api_functions.html#gadf6e67c88e75cbe44f52b5b93eecdd09">RCL_Scheduler_getCurrentTime</a></div><div class="ttdeci">static uint32_t RCL_Scheduler_getCurrentTime(void)</div><div class="ttdoc">Get current time.</div><div class="ttdef"><b>Definition:</b> RCL_Scheduler.h:233</div></div>
<div class="ttc" id="agroup__buffer_api_functions_html_gaf9be361ce2825a10f9ee8a132f8ad920"><div class="ttname"><a href="group__buffer_api_functions.html#gaf9be361ce2825a10f9ee8a132f8ad920">RCL_MultiBuffer_put</a></div><div class="ttdeci">void RCL_MultiBuffer_put(List_List *list, RCL_MultiBuffer *elem)</div><div class="ttdoc">Function to atomically put an elem onto the end of a multi buffer list.</div><div class="ttdef"><b>Definition:</b> RCL_Buffer.c:117</div></div>
<div class="ttc" id="agroup__buffer_api_functions_html_ga34d0923dddc433082c4d673e7331772d"><div class="ttname"><a href="group__buffer_api_functions.html#ga34d0923dddc433082c4d673e7331772d">RCL_MultiBuffer_RxEntry_get</a></div><div class="ttdeci">RCL_Buffer_DataEntry * RCL_MultiBuffer_RxEntry_get(List_List *list, List_List *consumedBuffers)</div><div class="ttdoc">Function to get the first entry in a MultiBuffer list.</div><div class="ttdef"><b>Definition:</b> RCL_Buffer.c:127</div></div>
<div class="ttc" id="a_r_c_l___event_8h_html_a9e6384116d9e2d84f36990827d6e86f1"><div class="ttname"><a href="_r_c_l___event_8h.html#a9e6384116d9e2d84f36990827d6e86f1">RCL_EventLastCmdDone</a></div><div class="ttdeci">#define RCL_EventLastCmdDone</div><div class="ttdef"><b>Definition:</b> RCL_Event.h:40</div></div>
<div class="ttc" id="a_r_c_l___command_8h_html_ae591a974abf55ca701cf33c61554e0cda1097a97f59467483fb55c8b471cb3036"><div class="ttname"><a href="_r_c_l___command_8h.html#ae591a974abf55ca701cf33c61554e0cda1097a97f59467483fb55c8b471cb3036">RCL_CommandStatus_Idle</a></div><div class="ttdeci">@ RCL_CommandStatus_Idle</div><div class="ttdef"><b>Definition:</b> RCL_Command.h:84</div></div>
<div class="ttc" id="agroup__buffer_api_functions_html_ga6fc3e5a4bff33ded64a77ea203128805"><div class="ttname"><a href="group__buffer_api_functions.html#ga6fc3e5a4bff33ded64a77ea203128805">RCL_TxBuffer_init</a></div><div class="ttdeci">uint8_t * RCL_TxBuffer_init(RCL_Buffer_TxBuffer *buffer, uint32_t numPad, uint32_t hdrLen, uint32_t dataLen)</div><div class="ttdoc">Function to initialize a TX buffer entry for use by RCL.</div><div class="ttdef"><b>Definition:</b> RCL_Buffer.c:69</div></div>
<div class="ttc" id="agroup__buffer_api_functions_html_gaf48f36094b2839027feea9b2ed3db023"><div class="ttname"><a href="group__buffer_api_functions.html#gaf48f36094b2839027feea9b2ed3db023">RCL_MultiBuffer_head</a></div><div class="ttdeci">static RCL_MultiBuffer * RCL_MultiBuffer_head(List_List *list)</div><div class="ttdoc">Function to return the head of a MultiBuffer list.</div><div class="ttdef"><b>Definition:</b> RCL_Buffer.h:257</div></div>
<div class="ttc" id="agroup__buffer_api_functions_html_gabbbf7364e16aae6951ee7c827de9bf06"><div class="ttname"><a href="group__buffer_api_functions.html#gabbbf7364e16aae6951ee7c827de9bf06">RCL_MultiBuffer_clear</a></div><div class="ttdeci">void RCL_MultiBuffer_clear(RCL_MultiBuffer *buffer)</div><div class="ttdoc">Function to clear a multi buffer entry for re-use by RCL.</div><div class="ttdef"><b>Definition:</b> RCL_Buffer.c:95</div></div>
<div class="ttc" id="a_r_c_l___command_8h_html_ade08c929505da062070474163417817da36e4eb855b1a8b435564f5911266a55b"><div class="ttname"><a href="_r_c_l___command_8h.html#ade08c929505da062070474163417817da36e4eb855b1a8b435564f5911266a55b">RCL_Schedule_AbsTime</a></div><div class="ttdeci">@ RCL_Schedule_AbsTime</div><div class="ttdef"><b>Definition:</b> RCL_Command.h:136</div></div>
<div class="ttc" id="a_r_c_l_8c_html_a145b90e0682b0e3fd914772879861e44"><div class="ttname"><a href="_r_c_l_8c.html#a145b90e0682b0e3fd914772879861e44">RCL_init</a></div><div class="ttdeci">int RCL_init(void)</div><div class="ttdoc">Initializes the RCL driver state.</div><div class="ttdef"><b>Definition:</b> RCL.c:537</div></div>
<div class="ttc" id="agroup__buffer_api_functions_html_ga9557389c0630c4bf6284036587279945"><div class="ttname"><a href="group__buffer_api_functions.html#ga9557389c0630c4bf6284036587279945">RCL_MultiBuffer_init</a></div><div class="ttdeci">void RCL_MultiBuffer_init(RCL_MultiBuffer *buffer, size_t size)</div><div class="ttdoc">Function to initialize a multi buffer entry for use by RCL.</div><div class="ttdef"><b>Definition:</b> RCL_Buffer.c:105</div></div>
<div class="ttc" id="acommands_2generic_8h_html_abf346875f81c8e9bbe0371a3e6cf9433"><div class="ttname"><a href="commands_2generic_8h.html#abf346875f81c8e9bbe0371a3e6cf9433">RCL_CmdNesbPtx_DefaultRuntime</a></div><div class="ttdeci">#define RCL_CmdNesbPtx_DefaultRuntime()</div><div class="ttdef"><b>Definition:</b> generic.h:354</div></div>
<div class="ttc" id="a_r_c_l___event_8h_html_a27efe993ce19cd501e8aadb7c5fa4aee"><div class="ttname"><a href="_r_c_l___event_8h.html#a27efe993ce19cd501e8aadb7c5fa4aee">RCL_EventRxEntryAvail</a></div><div class="ttdeci">#define RCL_EventRxEntryAvail</div><div class="ttdef"><b>Definition:</b> RCL_Event.h:41</div></div>
<div class="ttc" id="agroup__buffer_api_functions_html_ga05fa5798eb559b09a069b15bad0de4f1"><div class="ttname"><a href="group__buffer_api_functions.html#ga05fa5798eb559b09a069b15bad0de4f1">RCL_MultiBuffer_next</a></div><div class="ttdeci">static RCL_MultiBuffer * RCL_MultiBuffer_next(RCL_MultiBuffer *elem)</div><div class="ttdoc">Function to return the next elem in a linked list of MultiBuffers.</div><div class="ttdef"><b>Definition:</b> RCL_Buffer.h:272</div></div>
<div class="ttc" id="agroup__buffer_api_functions_html_gade3c0fd0ae25d389875981dac43d5f15"><div class="ttname"><a href="group__buffer_api_functions.html#gade3c0fd0ae25d389875981dac43d5f15">RCL_TxBuffer_len_u32</a></div><div class="ttdeci">#define RCL_TxBuffer_len_u32(numPad, hdrLen, dataLen)</div><div class="ttdoc">Total length of a TX buffer in 32-bit words, including all fields and padding.</div><div class="ttdef"><b>Definition:</b> RCL_Buffer.h:158</div></div>
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
<li class="navelem"><a class="el" href="rcl_architecture.html">RCL Architecture</a></li><li class="navelem"><a class="el" href="rcl_command_handlers.html">Command Handlers</a></li><li class="navelem"><a class="el" href="nesb_command_handlers.html">NESB Command Handlers</a></li>
<li class="footer">Generated by
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.18 </li>
</ul>
</div>
</body>
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.18"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Radio Control Layer (RCL): NESB PRX Command Handler</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="doxygen-awesome.css" rel="stylesheet" type="text/css"/>
<link href="doxygen-awesome-sidebar-only.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">Radio Control Layer (RCL)
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.18 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function(){initNavTree('nesb_prx_handler.html',''); initResizable(); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div class="PageDoc"><div class="header">
<div class="headertitle">
<div class="title">NESB PRX Command Handler </div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h1><a class="anchor" id="autotoc_md41"></a>
Introduction</h1>
<p>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.</p>
<p>The following sections describe how the command can be configured and used, its life cycle, and how it fits into the <a class="el" href="_r_c_l_8h.html#struct_r_c_l" title="Global shared driver state.">RCL</a> architecture.</p>
<h1><a class="anchor" id="autotoc_md42"></a>
Usage</h1>
<p>In order to submit a PRX command, the following steps must have taken place:</p>
<ol type="1">
<li><a class="el" href="_r_c_l_8h.html#struct_r_c_l" title="Global shared driver state.">RCL</a> has been initialized (See <a class="el" href="_r_c_l_8h.html#a2fa1415c07a809621287abfc9b7f40f7" title="Initializes the RCL driver state.">RCL_init</a>) and a handle must exist (See <a class="el" href="_r_c_l_8h.html#ad250dbda0747820e489d38cdb268ecee" title="Initializes an RCL client instance.">RCL_open</a>).</li>
<li>The <a class="el" href="commands_2generic_8h.html#struct_r_c_l___c_m_d___n_e_s_b___p_r_x__t" title="NESB receive command.">RCL_CMD_NESB_PRX_t</a> command has been initialized and configured.</li>
<li>A Multibuffer has been set up to receive the incoming packets.</li>
</ol>
<p>Once these steps have been completed, <a class="el" href="_r_c_l_8h.html#a335ebd06e9591a1a9ec26bde80199d96" title="Submit RCL command object to be scheduled for execution.">RCL_Command_submit</a> and <a class="el" href="_r_c_l_8h.html#adc809f6096147ac6e33641fb2161a859" title="Wait for a submitted command to complete.">RCL_Command_pend</a> are called to effectively send a packet and then wait for the command to conclude.</p>
<p>As with any command handler, the application must built packets so that they are compatible with the internal packet format used in the LRF. Having said this, NESB packets also have a specific packet format that needs to be considered at the application level.</p>
<p>This can be accomplished by using a struct to define the various fields that need to be considered when building or checking the content of the packet.</p>
<div class="fragment"><div class="line"><span class="preprocessor">#define PKT_LEN 200</span></div>
<div class="line"><span class="preprocessor">#define HDR_LEN 3</span></div>
<div class="line"><span class="preprocessor">#define NUM_PKT 4</span></div>
<div class="line"><span class="preprocessor">#define NUM_PAD 3</span></div>
<div class="line"><span class="preprocessor">#define NUM_RX_BUF 1</span></div>
<div class="line"><span class="preprocessor">#define MULTI_BUF_SZ 2048</span></div>
<div class="line"><span class="preprocessor">#define FREQUENCY 2470000000</span></div>
<div class="line"><span class="preprocessor">#define SYNCWORD 0xAB0B51DE</span></div>
<div class="line"><span class="preprocessor">#define NESB_ADDR 0xAC9825CB</span></div>
<div class="line"> </div>
<div class="line"><span class="preprocessor">#define NESB_hdrDef_Default() \</span></div>
<div class="line"><span class="preprocessor">{ \</span></div>
<div class="line"><span class="preprocessor"> .numHdrBits = 11, \</span></div>
<div class="line"><span class="preprocessor"> .numLenBits = 8, \</span></div>
<div class="line"><span class="preprocessor"> .lenPos = 3, \</span></div>
<div class="line"><span class="preprocessor"> .lenOffset = 0, \</span></div>
<div class="line"><span class="preprocessor"> .numPad = 3, \</span></div>
<div class="line"><span class="preprocessor">}</span></div>
<div class="line"><span class="preprocessor">#define NESB_hdrDef_DefaultRuntime() (ExampleRCL_NesbHdrDef) NESB_hdrDef_Default()</span></div>
<div class="line"> </div>
<div class="line"><span class="keyword">typedef</span> <span class="keyword">struct </span>{</div>
<div class="line"> uint8_t numHdrBits;</div>
<div class="line"> uint8_t numLenBits;</div>
<div class="line"> uint8_t lenPos;</div>
<div class="line"> int8_t lenOffset;</div>
<div class="line"> uint8_t numPad;</div>
<div class="line">} ExampleRCL_NesbHdrDef;</div>
</div><!-- fragment --><p> Taking this into consideration, packet generation needs to consider how the 11-bit header is placed in the LRF FIFO. the following function shows one way to accomplish this:</p>
<div class="fragment"><div class="line"><span class="keywordtype">void</span> generatePackets(RCL_Buffer_TxBuffer **txBuffers, uint32_t numPkt, uint32_t pktLen,</div>
<div class="line"> ExampleRCL_NesbHdrDef *hdrDef, uint32_t address, uint32_t addressLen)</div>
<div class="line">{</div>
<div class="line"> <span class="keyword">union</span></div>
<div class="line"> {</div>
<div class="line"> uint32_t value;</div>
<div class="line"> uint8_t bytes[4];</div>
<div class="line"> } nesbAddress;</div>
<div class="line"> <span class="keyword">union</span></div>
<div class="line"> {</div>
<div class="line"> uint16_t value;</div>
<div class="line"> uint8_t bytes[2];</div>
<div class="line"> } nesbHeader;</div>
<div class="line"> </div>
<div class="line"> uint8_t hdrLen = (hdrDef->numHdrBits + 7) / 8;</div>
<div class="line"> uint8_t seqNum = 0; <span class="comment">// Start with a seq number equal to zero</span></div>
<div class="line"> uint8_t noAckBit = 0; <span class="comment">// Always set the noAckBit to zero</span></div>
<div class="line"> nesbAddress.value = address;</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < numPkt; i++)</div>
<div class="line"> {</div>
<div class="line"> uint8_t *txData;</div>
<div class="line"> </div>
<div class="line"> <span class="comment">/* Initialize Tx Buffer */</span></div>
<div class="line"> txData = <a class="code" href="group__buffer_api_functions.html#ga6fc3e5a4bff33ded64a77ea203128805">RCL_TxBuffer_init</a>(txBuffers[i], hdrDef->numPad, hdrLen, pktLen);</div>
<div class="line"> </div>
<div class="line"> <span class="comment">/* Build the 11 bit NESB header */</span></div>
<div class="line"> nesbHeader.value = ((pktLen << 3) | (seqNum << 1) | noAckBit);</div>
<div class="line"> </div>
<div class="line"> <span class="comment">/* Write NESB header to buffer */</span></div>
<div class="line"> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < hdrLen; i++)</div>
<div class="line"> {</div>
<div class="line"> txData[i] = nesbHeader.bytes[i];</div>
<div class="line"> }</div>
<div class="line"> <span class="comment">/* Write NESB address to buffer. Address comes immediately after header */</span></div>
<div class="line"> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < addressLen; i++)</div>
<div class="line"> {</div>
<div class="line"> txData[hdrLen + i] = nesbAddress.bytes[i];</div>
<div class="line"> }</div>
<div class="line"> <span class="comment">/* Write the payload */</span></div>
<div class="line"> <span class="keywordflow">if</span>(pktLen >= addressLen)</div>
<div class="line"> {</div>
<div class="line"> uint32_t payloadLength = pktLen - addressLen;</div>
<div class="line"> <span class="keywordflow">for</span>(uint32_t i = 0; i < payloadLength; i++)</div>
<div class="line"> {</div>
<div class="line"> txData[hdrLen + addressLen + i] = i & 0xFF;</div>
<div class="line"> }</div>
<div class="line"> }</div>
<div class="line"> <span class="comment">/* Update packet ID (seq number) for next packet */</span></div>
<div class="line"> seqNum = (seqNum + 1) % 4;</div>
<div class="line"> }</div>
<div class="line">}</div>
</div><!-- fragment --><p> 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.</p>
<div class="fragment"><div class="line"><span class="preprocessor">#define NUM_RX_BUF 1</span></div>
<div class="line"><span class="preprocessor">#define MULTI_BUF_SZ 2048</span></div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">void</span> runNesbPrx(<span class="keywordtype">void</span>)</div>
<div class="line">{</div>
<div class="line"> uint32_t rxMultiBuffer[NUM_RX_BUF][MULTI_BUF_SZ / 4];</div>
<div class="line"> List_List multiBuffers = { 0 };</div>
<div class="line"> </div>
<div class="line"> <a class="code" href="_r_c_l_8c.html#a145b90e0682b0e3fd914772879861e44">RCL_init</a>();</div>
<div class="line"> RCL_Handle h = <a class="code" href="_r_c_l_8c.html#ad250dbda0747820e489d38cdb268ecee">RCL_open</a>(&rclClient, &LRF_configNesb);</div>
<div class="line"> </div>
<div class="line"> <span class="comment">/* Declare command */</span></div>
<div class="line"> RCL_CmdNesbPrx cmd;</div>
<div class="line"> cmd = <a class="code" href="commands_2generic_8h.html#aa3f20f7a02b6bb444a48846c8a322cd3">RCL_CmdNesbPrx_DefaultRuntime</a>();</div>
<div class="line"> RCL_StatsNesb rxStats;</div>
<div class="line"> rxStats = <a class="code" href="commands_2generic_8h.html#a10b0c9e2e88c99a8b03e3ac82df0445e">RCL_StatsNesb_DefaultRuntime</a>();</div>
<div class="line"> </div>
<div class="line"> <span class="comment">/* Command configuration */</span></div>
<div class="line"> cmd.common.scheduling = <a class="code" href="_r_c_l___command_8h.html#ade08c929505da062070474163417817da36e4eb855b1a8b435564f5911266a55b">RCL_Schedule_AbsTime</a>;</div>
<div class="line"> cmd.common.runtime.callback = defaultCallback;</div>
<div class="line"> cmd.common.runtime.rclCallbackMask.value = <a class="code" href="_r_c_l___event_8h.html#a9e6384116d9e2d84f36990827d6e86f1">RCL_EventLastCmdDone</a>.value | <a class="code" href="_r_c_l___event_8h.html#a27efe993ce19cd501e8aadb7c5fa4aee">RCL_EventRxEntryAvail</a>.value;</div>
<div class="line"> cmd.rfFrequency = FREQUENCY;</div>
<div class="line"> cmd.syncWordA = SYNCWORD;</div>
<div class="line"> cmd.syncWord[0].address = NESB_ADDR; <span class="comment">// Set NESB address</span></div>
<div class="line"> cmd.addrLen = 4; <span class="comment">// Consider 4 bytes for the NESB address</span></div>
<div class="line"> cmd.syncWord[0].seqValid = 1; <span class="comment">// Only accept packets with sequence number and CRC different from the previous one</span></div>
<div class="line"> cmd.syncWord[0].autoAckMode = 3; <span class="comment">// Enable auto-acknowledgement regardless of received NO_ACK.</span></div>
<div class="line"> </div>
<div class="line"> <span class="comment">/* Stats configuration */</span></div>
<div class="line"> rxStats.config.accumulate = 1;</div>
<div class="line"> rxStats.nTx = 0;</div>
<div class="line"> rxStats.nRxOk = 0;</div>
<div class="line"> rxStats.nRxNok = 0;</div>
<div class="line"> rxStats.nRxIgnored = 0;</div>
<div class="line"> rxStats.nRxAddrMismatch = 0;</div>
<div class="line"> rxStats.nRxBufFull = 0;</div>
<div class="line"> </div>
<div class="line"> <span class="comment">/* Set up Rx (multi)buffer */</span></div>
<div class="line"> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < NUM_RX_BUF; i++)</div>
<div class="line"> {</div>
<div class="line"> RCL_MultiBuffer *multiBuffer = (RCL_MultiBuffer *) rxMultiBuffer[i];</div>
<div class="line"> <a class="code" href="group__buffer_api_functions.html#ga9557389c0630c4bf6284036587279945">RCL_MultiBuffer_init</a>(multiBuffer, MULTI_BUF_SZ);</div>
<div class="line"> <a class="code" href="group__buffer_api_functions.html#gaf9be361ce2825a10f9ee8a132f8ad920">RCL_MultiBuffer_put</a>(&multiBuffers, multiBuffer);</div>
<div class="line"> }</div>
<div class="line"> </div>
<div class="line"> <span class="comment">/* Setup a graceful stop time */</span></div>
<div class="line"> uint32_t ticksPerByte = <a class="code" href="_r_c_l___scheduler_8h.html#acdfb6b54cdc9e000704111729a8319a7">RCL_SCHEDULER_SYSTIM_US</a>(8);</div>
<div class="line"> uint32_t startDelay = <a class="code" href="_r_c_l___scheduler_8h.html#acdfb6b54cdc9e000704111729a8319a7">RCL_SCHEDULER_SYSTIM_US</a>(600);</div>
<div class="line"> uint32_t endPktDelay = <a class="code" href="_r_c_l___scheduler_8h.html#acdfb6b54cdc9e000704111729a8319a7">RCL_SCHEDULER_SYSTIM_US</a>(150);</div>
<div class="line"> uint32_t packetOffset = ticksPerByte * 10 + endPktDelay;</div>
<div class="line"> uint32_t pktInterval = ticksPerByte * cmd.syncWord[0].maxPktLen + packetOffset;</div>
<div class="line"> cmd.common.timing.relGracefulStopTime = startDelay + NUM_PKT * pktInterval;</div>
<div class="line"> cmd.stats = &rxStats;</div>
<div class="line"> </div>
<div class="line"> <span class="comment">/* Clear multi buffers before starting */</span></div>
<div class="line"> RCL_MultiBuffer *multiBuffer = <a class="code" href="group__buffer_api_functions.html#gaf48f36094b2839027feea9b2ed3db023">RCL_MultiBuffer_head</a>(&multiBuffers);</div>
<div class="line"> <span class="keywordflow">while</span> (multiBuffer != NULL)</div>
<div class="line"> {</div>
<div class="line"> <a class="code" href="group__buffer_api_functions.html#gabbbf7364e16aae6951ee7c827de9bf06">RCL_MultiBuffer_clear</a>(multiBuffer);</div>
<div class="line"> multiBuffer = <a class="code" href="group__buffer_api_functions.html#ga05fa5798eb559b09a069b15bad0de4f1">RCL_MultiBuffer_next</a>(multiBuffer);</div>
<div class="line"> }</div>
<div class="line"> cmd.rxBuffers = multiBuffers;</div>
<div class="line"> </div>
<div class="line"> <span class="comment">/* Schedule command considering a start delay of 600 us */</span></div>
<div class="line"> uint32_t nextTime = <a class="code" href="group__timing_api_functions.html#gadf6e67c88e75cbe44f52b5b93eecdd09">RCL_Scheduler_getCurrentTime</a>() + <a class="code" href="_r_c_l___scheduler_8h.html#acdfb6b54cdc9e000704111729a8319a7">RCL_SCHEDULER_SYSTIM_US</a>(600);</div>
<div class="line"> cmd.common.timing.absStartTime = nextTime;</div>
<div class="line"> </div>
<div class="line"> <a class="code" href="_r_c_l_8c.html#a335ebd06e9591a1a9ec26bde80199d96">RCL_Command_submit</a>(h, &cmd);</div>
<div class="line"> <span class="comment">/* Wait for command to conclude */</span></div>
<div class="line"> <a class="code" href="_r_c_l_8c.html#adc809f6096147ac6e33641fb2161a859">RCL_Command_pend</a>(&cmd);</div>
<div class="line"> </div>
<div class="line"> <span class="comment">/* Check the packet contents */</span></div>
<div class="line"> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < NUM_PKT; i++)</div>
<div class="line"> {</div>
<div class="line"> RCL_Buffer_DataEntry *rxPkt = <a class="code" href="group__buffer_api_functions.html#ga34d0923dddc433082c4d673e7331772d">RCL_MultiBuffer_RxEntry_get</a>(&cmd.rxBuffers, NULL);</div>
<div class="line"> <span class="keywordflow">if</span> (rxPkt != NULL)</div>
<div class="line"> {</div>
<div class="line"> <span class="comment">/* Do something with the received data */</span></div>
<div class="line"> }</div>
<div class="line"> }</div>
<div class="line">}</div>
</div><!-- fragment --><h1><a class="anchor" id="autotoc_md43"></a>
Architecture</h1>
<p>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.</p>
<div class="plantumlgraph">
<img src="inline_umlgraph_9.png" />
<div class="caption">
NESB PRX handler state machine</div>
</div>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone"><a class="el" href="_r_c_l_8h.html#struct_r_c_l" title="Global shared driver state.">RCL</a> Event (In) </th><th class="markdownTableHeadNone">Description </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone"><em>setup</em> </td><td class="markdownTableBodyNone">Setup has been performed </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone"><em>timerStart</em> </td><td class="markdownTableBodyNone">Timer-based start signalled </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone"><em>rxBufferUpdate</em> </td><td class="markdownTableBodyNone">RX buffer has been updated </td></tr>
</table>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone"><a class="el" href="_r_c_l_8h.html#struct_r_c_l" title="Global shared driver state.">RCL</a> Event (Out) </th><th class="markdownTableHeadNone">Description </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone"><em>lastCmdDone</em> </td><td class="markdownTableBodyNone">The <a class="el" href="_r_c_l_8h.html#struct_r_c_l" title="Global shared driver state.">RCL</a> is finished with the command </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone"><em>cmdStarted</em> </td><td class="markdownTableBodyNone">Command handler has accepted and started executing </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone"><em>rxBufferFinished</em> </td><td class="markdownTableBodyNone">An RX multi-buffer is finished </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone"><em>rxEntryAvail</em> </td><td class="markdownTableBodyNone">An RX entry has been made available </td></tr>
</table>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">LRF Event </th><th class="markdownTableHeadNone">Description </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone"><em>opDone</em> </td><td class="markdownTableBodyNone">The PBE operation has finished </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone"><em>opError</em> </td><td class="markdownTableBodyNone">Something went wrong. Cause located in the PBE ENDCAUSE register </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone"><em>rxOk</em> </td><td class="markdownTableBodyNone">Packet received with CRC OK and not to be ignored by the MCU </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone"><em>rxNok</em> </td><td class="markdownTableBodyNone">Packet received with CRC error </td></tr>
</table>
</div></div><!-- contents -->
</div><!-- PageDoc -->
</div><!-- doc-content -->
<div class="ttc" id="a_r_c_l_8c_html_adc809f6096147ac6e33641fb2161a859"><div class="ttname"><a href="_r_c_l_8c.html#adc809f6096147ac6e33641fb2161a859">RCL_Command_pend</a></div><div class="ttdeci">RCL_CommandStatus RCL_Command_pend(RCL_Command_Handle c)</div><div class="ttdoc">Wait for a submitted command to complete.</div><div class="ttdef"><b>Definition:</b> RCL.c:667</div></div>
<div class="ttc" id="a_r_c_l_8c_html_ad250dbda0747820e489d38cdb268ecee"><div class="ttname"><a href="_r_c_l_8c.html#ad250dbda0747820e489d38cdb268ecee">RCL_open</a></div><div class="ttdeci">RCL_Handle RCL_open(RCL_Client *c, const LRF_Config *lrfConfig)</div><div class="ttdoc">Initializes an RCL client instance.</div><div class="ttdef"><b>Definition:</b> RCL.c:554</div></div>
<div class="ttc" id="a_r_c_l___scheduler_8h_html_acdfb6b54cdc9e000704111729a8319a7"><div class="ttname"><a href="_r_c_l___scheduler_8h.html#acdfb6b54cdc9e000704111729a8319a7">RCL_SCHEDULER_SYSTIM_US</a></div><div class="ttdeci">#define RCL_SCHEDULER_SYSTIM_US(x)</div><div class="ttdef"><b>Definition:</b> RCL_Scheduler.h:45</div></div>
<div class="ttc" id="a_r_c_l_8c_html_a335ebd06e9591a1a9ec26bde80199d96"><div class="ttname"><a href="_r_c_l_8c.html#a335ebd06e9591a1a9ec26bde80199d96">RCL_Command_submit</a></div><div class="ttdeci">RCL_CommandStatus RCL_Command_submit(RCL_Handle h, RCL_Command_Handle c)</div><div class="ttdoc">Submit RCL command object to be scheduled for execution.</div><div class="ttdef"><b>Definition:</b> RCL.c:633</div></div>
<div class="ttc" id="acommands_2generic_8h_html_a10b0c9e2e88c99a8b03e3ac82df0445e"><div class="ttname"><a href="commands_2generic_8h.html#a10b0c9e2e88c99a8b03e3ac82df0445e">RCL_StatsNesb_DefaultRuntime</a></div><div class="ttdeci">#define RCL_StatsNesb_DefaultRuntime()</div><div class="ttdef"><b>Definition:</b> generic.h:467</div></div>
<div class="ttc" id="agroup__timing_api_functions_html_gadf6e67c88e75cbe44f52b5b93eecdd09"><div class="ttname"><a href="group__timing_api_functions.html#gadf6e67c88e75cbe44f52b5b93eecdd09">RCL_Scheduler_getCurrentTime</a></div><div class="ttdeci">static uint32_t RCL_Scheduler_getCurrentTime(void)</div><div class="ttdoc">Get current time.</div><div class="ttdef"><b>Definition:</b> RCL_Scheduler.h:233</div></div>
<div class="ttc" id="agroup__buffer_api_functions_html_gaf9be361ce2825a10f9ee8a132f8ad920"><div class="ttname"><a href="group__buffer_api_functions.html#gaf9be361ce2825a10f9ee8a132f8ad920">RCL_MultiBuffer_put</a></div><div class="ttdeci">void RCL_MultiBuffer_put(List_List *list, RCL_MultiBuffer *elem)</div><div class="ttdoc">Function to atomically put an elem onto the end of a multi buffer list.</div><div class="ttdef"><b>Definition:</b> RCL_Buffer.c:117</div></div>
<div class="ttc" id="agroup__buffer_api_functions_html_ga34d0923dddc433082c4d673e7331772d"><div class="ttname"><a href="group__buffer_api_functions.html#ga34d0923dddc433082c4d673e7331772d">RCL_MultiBuffer_RxEntry_get</a></div><div class="ttdeci">RCL_Buffer_DataEntry * RCL_MultiBuffer_RxEntry_get(List_List *list, List_List *consumedBuffers)</div><div class="ttdoc">Function to get the first entry in a MultiBuffer list.</div><div class="ttdef"><b>Definition:</b> RCL_Buffer.c:127</div></div>
<div class="ttc" id="a_r_c_l___event_8h_html_a9e6384116d9e2d84f36990827d6e86f1"><div class="ttname"><a href="_r_c_l___event_8h.html#a9e6384116d9e2d84f36990827d6e86f1">RCL_EventLastCmdDone</a></div><div class="ttdeci">#define RCL_EventLastCmdDone</div><div class="ttdef"><b>Definition:</b> RCL_Event.h:40</div></div>
<div class="ttc" id="agroup__buffer_api_functions_html_ga6fc3e5a4bff33ded64a77ea203128805"><div class="ttname"><a href="group__buffer_api_functions.html#ga6fc3e5a4bff33ded64a77ea203128805">RCL_TxBuffer_init</a></div><div class="ttdeci">uint8_t * RCL_TxBuffer_init(RCL_Buffer_TxBuffer *buffer, uint32_t numPad, uint32_t hdrLen, uint32_t dataLen)</div><div class="ttdoc">Function to initialize a TX buffer entry for use by RCL.</div><div class="ttdef"><b>Definition:</b> RCL_Buffer.c:69</div></div>
<div class="ttc" id="agroup__buffer_api_functions_html_gaf48f36094b2839027feea9b2ed3db023"><div class="ttname"><a href="group__buffer_api_functions.html#gaf48f36094b2839027feea9b2ed3db023">RCL_MultiBuffer_head</a></div><div class="ttdeci">static RCL_MultiBuffer * RCL_MultiBuffer_head(List_List *list)</div><div class="ttdoc">Function to return the head of a MultiBuffer list.</div><div class="ttdef"><b>Definition:</b> RCL_Buffer.h:257</div></div>
<div class="ttc" id="agroup__buffer_api_functions_html_gabbbf7364e16aae6951ee7c827de9bf06"><div class="ttname"><a href="group__buffer_api_functions.html#gabbbf7364e16aae6951ee7c827de9bf06">RCL_MultiBuffer_clear</a></div><div class="ttdeci">void RCL_MultiBuffer_clear(RCL_MultiBuffer *buffer)</div><div class="ttdoc">Function to clear a multi buffer entry for re-use by RCL.</div><div class="ttdef"><b>Definition:</b> RCL_Buffer.c:95</div></div>
<div class="ttc" id="a_r_c_l___command_8h_html_ade08c929505da062070474163417817da36e4eb855b1a8b435564f5911266a55b"><div class="ttname"><a href="_r_c_l___command_8h.html#ade08c929505da062070474163417817da36e4eb855b1a8b435564f5911266a55b">RCL_Schedule_AbsTime</a></div><div class="ttdeci">@ RCL_Schedule_AbsTime</div><div class="ttdef"><b>Definition:</b> RCL_Command.h:136</div></div>
<div class="ttc" id="a_r_c_l_8c_html_a145b90e0682b0e3fd914772879861e44"><div class="ttname"><a href="_r_c_l_8c.html#a145b90e0682b0e3fd914772879861e44">RCL_init</a></div><div class="ttdeci">int RCL_init(void)</div><div class="ttdoc">Initializes the RCL driver state.</div><div class="ttdef"><b>Definition:</b> RCL.c:537</div></div>
<div class="ttc" id="agroup__buffer_api_functions_html_ga9557389c0630c4bf6284036587279945"><div class="ttname"><a href="group__buffer_api_functions.html#ga9557389c0630c4bf6284036587279945">RCL_MultiBuffer_init</a></div><div class="ttdeci">void RCL_MultiBuffer_init(RCL_MultiBuffer *buffer, size_t size)</div><div class="ttdoc">Function to initialize a multi buffer entry for use by RCL.</div><div class="ttdef"><b>Definition:</b> RCL_Buffer.c:105</div></div>
<div class="ttc" id="acommands_2generic_8h_html_aa3f20f7a02b6bb444a48846c8a322cd3"><div class="ttname"><a href="commands_2generic_8h.html#aa3f20f7a02b6bb444a48846c8a322cd3">RCL_CmdNesbPrx_DefaultRuntime</a></div><div class="ttdeci">#define RCL_CmdNesbPrx_DefaultRuntime()</div><div class="ttdef"><b>Definition:</b> generic.h:441</div></div>
<div class="ttc" id="a_r_c_l___event_8h_html_a27efe993ce19cd501e8aadb7c5fa4aee"><div class="ttname"><a href="_r_c_l___event_8h.html#a27efe993ce19cd501e8aadb7c5fa4aee">RCL_EventRxEntryAvail</a></div><div class="ttdeci">#define RCL_EventRxEntryAvail</div><div class="ttdef"><b>Definition:</b> RCL_Event.h:41</div></div>
<div class="ttc" id="agroup__buffer_api_functions_html_ga05fa5798eb559b09a069b15bad0de4f1"><div class="ttname"><a href="group__buffer_api_functions.html#ga05fa5798eb559b09a069b15bad0de4f1">RCL_MultiBuffer_next</a></div><div class="ttdeci">static RCL_MultiBuffer * RCL_MultiBuffer_next(RCL_MultiBuffer *elem)</div><div class="ttdoc">Function to return the next elem in a linked list of MultiBuffers.</div><div class="ttdef"><b>Definition:</b> RCL_Buffer.h:272</div></div>
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
<li class="navelem"><a class="el" href="rcl_architecture.html">RCL Architecture</a></li><li class="navelem"><a class="el" href="rcl_command_handlers.html">Command Handlers</a></li><li class="navelem"><a class="el" href="nesb_command_handlers.html">NESB Command Handlers</a></li>
<li class="footer">Generated by
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.18 </li>
</ul>
</div>
</body>
</html>
