Sophie

Sophie

distrib > Mageia > 7 > i586 > by-pkgid > 2bcfde21a73ffa0573b5ca7b311a2f76 > files > 210

bladerf-doc-2018.12-0.rc3.1.mga7.noarch.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://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.11"/>
<title>libbladeRF: Synchronous Interface: Scheduled TX bursts</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="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>
<script type="text/javascript">
  $(document).ready(function() { init_search(); });
</script>
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    extensions: ["tex2jax.js"],
    jax: ["input/TeX","output/HTML-CSS"],
});
</script><script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js"></script>
<link href="doxygen.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="projectlogo"><img alt="Logo" src="logo.png"/></td>
  <td id="projectalign" style="padding-left: 0.5em;">
   <div id="projectname">libbladeRF
   &#160;<span id="projectnumber">1.7.2</span>
   </div>
   <div id="projectbrief">Nuand bladeRF library</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.11 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li><a href="modules.html"><span>API&#160;Sections</span></a></li>
      <li>
        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <img id="MSearchSelect" src="search/mag_sel.png"
               onmouseover="return searchBox.OnSearchSelectShow()"
               onmouseout="return searchBox.OnSearchSelectHide()"
               alt=""/>
          <input type="text" id="MSearchField" value="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
          </span>
        </div>
      </li>
    </ul>
  </div>
<!-- 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><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">Synchronous Interface: Scheduled TX bursts </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>This page describes how to use the bladeRF <a href="group___f_n___d_a_t_a___s_y_n_c.html" class="el">Synchronous Interface</a> to transmit bursts of samples at a specified timestamp. The timestamp is a free-running counter in the FPGA, incrementing at the sample rate specified by <a class="el" href="group___f_n___s_a_m_p_l_i_n_g.html#ga248121816cd4621abf833df906ca0761">bladerf_set_sample_rate()</a>, with each outgoing sample.</p>
<h2>Configuring the Synchronous Interface</h2>
<p>When timestamps are desired, one must enable metadata support. This is done through the <code>format</code> parameter of the <a class="el" href="group___f_n___d_a_t_a___s_y_n_c.html#gacde68e74a8f7d27100b071634b2e65c5">bladerf_sync_config()</a> function:</p>
<div class="fragment"><div class="line"></div><div class="line">    <span class="comment">/* Configure the device&#39;s TX module for use with the sync interface.</span></div><div class="line"><span class="comment">     * SC16 Q11 samples *with* metadata are used. */</span></div><div class="line">    status = <a class="code" href="group___f_n___d_a_t_a___s_y_n_c.html#gacde68e74a8f7d27100b071634b2e65c5">bladerf_sync_config</a>(dev,</div><div class="line">                                 <a class="code" href="group___f_n___m_o_d_u_l_e.html#ggab12571146a3d4c5d79ac497a74b3fb5ea2b59868119a050b6f0e24631ffbb16e3">BLADERF_MODULE_TX</a>,</div><div class="line">                                 <a class="code" href="group___f_m_t___m_e_t_a.html#gga4c61587834fd4de51a8e2d34e14a73b2a4af3974535ba338bbcecaa8d7500de03">BLADERF_FORMAT_SC16_Q11_META</a>,</div><div class="line">                                 num_buffers,</div><div class="line">                                 buffer_size,</div><div class="line">                                 num_transfers,</div><div class="line">                                 timeout_ms);</div><div class="line"></div><div class="line">    <span class="keywordflow">if</span> (status != 0) {</div><div class="line">        fprintf(stderr, <span class="stringliteral">&quot;Failed to configure TX sync interface: %s\n&quot;</span>,</div><div class="line">                <a class="code" href="group___r_e_t_c_o_d_e_s.html#ga689e0c91e6abb8b5575a929453e4dbcc">bladerf_strerror</a>(status));</div><div class="line"></div><div class="line">        <span class="keywordflow">goto</span> error;</div><div class="line">    }</div><div class="line"></div></div><!-- fragment --><p> Descriptions of the other parameters may be found in the <a href="sync_no_meta.html" class="el">Synchronous Interface: Basic usage without metadata</a> page.</p>
<p>Remember to enable the module via <a class="el" href="group___f_n___m_o_d_u_l_e.html#gabef14480bd8483eaf937b30a4b5eab88">bladerf_enable_module()</a> <em>after</em> calling <a class="el" href="group___f_n___d_a_t_a___s_y_n_c.html#gacde68e74a8f7d27100b071634b2e65c5">bladerf_sync_config()</a>, and <em>before</em> attempting to call <a class="el" href="group___f_n___d_a_t_a___s_y_n_c.html#gac4a13bf1cb10d9a3e547b8c654268c35">bladerf_sync_tx()</a>.</p>
<p>Also ensure that <a class="el" href="group___f_n___d_a_t_a___s_y_n_c.html#gacde68e74a8f7d27100b071634b2e65c5">bladerf_sync_config()</a> has been called before attempting to read timestamps via <a class="el" href="group___f_m_t___m_e_t_a.html#ga9b03a1b2254eab471f789627c3bde408">bladerf_get_timestamp()</a>.</p>
<h2>Burst Transmissions</h2>
<p>The synchronous interface allows a burst of samples to be transmitted at a specified timestamp value. The hardware will output zeros after the burst.</p>
<p>The general procedure for transmitting a burst is as follows</p>
<ul>
<li>
<p class="startli">Call <a class="el" href="group___f_n___d_a_t_a___s_y_n_c.html#gac4a13bf1cb10d9a3e547b8c654268c35">bladerf_sync_tx()</a> with <a class="el" href="structbladerf__metadata.html#a773b39d480759f67926cb18ae2219281">bladerf_metadata.flags</a> set to <a class="el" href="group___f_m_t___m_e_t_a.html#ga2aef16902d542172be1b87917d89de10">BLADERF_META_FLAG_TX_BURST_START</a> and <a class="el" href="structbladerf__metadata.html#a465bef81f6478756e5443025b1f2ddfa">bladerf_metadata.timestamp</a> set to the timestamp at which samples should be transmitted.</p>
<p class="endli"></p>
</li>
<li>
<p class="startli">Make successive <a class="el" href="group___f_n___d_a_t_a___s_y_n_c.html#gac4a13bf1cb10d9a3e547b8c654268c35">bladerf_sync_tx()</a> calls with <a class="el" href="structbladerf__metadata.html#a773b39d480759f67926cb18ae2219281">bladerf_metadata.flags</a> set to 0. These samples will be contiguously appended to the previous samples. The <a class="el" href="structbladerf__metadata.html#a465bef81f6478756e5443025b1f2ddfa">bladerf_metadata.timestamp</a> field is not used at this point; the caller does not need to worry about advancing it.</p>
<p class="endli"></p>
</li>
<li>
Call <a class="el" href="group___f_n___d_a_t_a___s_y_n_c.html#gac4a13bf1cb10d9a3e547b8c654268c35">bladerf_sync_tx()</a> with the final samples in the burst and the <a class="el" href="structbladerf__metadata.html#a773b39d480759f67926cb18ae2219281">bladerf_metadata.flags</a> set to <a class="el" href="group___f_m_t___m_e_t_a.html#gaa9a2d61688c4b775b52a0acfed32f50a">BLADERF_META_FLAG_TX_BURST_END</a>. This will complete the burst, flush any remaining samples in the synchronous interface's current internal buffer, and write the buffer to the device. Similar to the previous step, any samples provided at this points will be contiguously appended to prior samples, and the <a class="el" href="structbladerf__metadata.html#a465bef81f6478756e5443025b1f2ddfa">bladerf_metadata.timestamp</a> field will not be used. </li>
</ul>
<p>The above procedure is useful when the samples for the burst are actively being produced.</p>
<p>If all the samples for the burst are available ahead of time, all of the above steps can be performed with a single function call, with: </p><ul>
<li>
<p class="startli"><a class="el" href="structbladerf__metadata.html#a773b39d480759f67926cb18ae2219281">bladerf_metadata.flags</a> set to: <code>(BLADERF_META_FLAG_TX_BURST_START | BLADERF_META_FLAG_TX_BURST_END)</code> </p>
<p class="endli"></p>
</li>
<li>
<a class="el" href="structbladerf__metadata.html#a465bef81f6478756e5443025b1f2ddfa">bladerf_metadata.timestamp</a> set to the timestamp at which the samples should be transmitted.  </li>
</ul>
<p>Note that when completing a burst with <a class="el" href="group___f_m_t___m_e_t_a.html#gaa9a2d61688c4b775b52a0acfed32f50a">BLADERF_META_FLAG_TX_BURST_END</a>, up to one of the synchronous interface's buffers may be flushed. This is important to consider, since this defines the minimum value of the next timestamp can be provided.</p>
<p>If small bursts need to be scheduled back to back, consider either manually zero-padding between them, or using the <a class="el" href="group___f_m_t___m_e_t_a.html#gacc23fedbd8cf35143670969718ca46cb">BLADERF_META_FLAG_TX_UPDATE_TIMESTAMP</a> flag, as described in one of the following sections.</p>
<p><br />
 </p><h2>Waiting for TX to complete</h2>
<p>When scheduling transmissions, one must ensure the samples have reached the RF front end before shutting the stream down and disabling the TX module.</p>
<p>This can be achieved by polling the TX timestamp and waiting for it to exceed the value of the last sample. Generally, one should wait some additional time to account for some group delay in the signal path.</p>
<p>Below is an example <code>wait_for_timestamp()</code> function that provides this functionality, with a simple timeout:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> wait_for_timestamp(<span class="keyword">struct</span> bladerf *dev, <a class="code" href="group___f_n___m_o_d_u_l_e.html#gab12571146a3d4c5d79ac497a74b3fb5e">bladerf_module</a> module,</div><div class="line">                       uint64_t <a class="code" href="structbladerf__metadata.html#a465bef81f6478756e5443025b1f2ddfa">timestamp</a>, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> timeout_ms)</div><div class="line">{</div><div class="line">    <span class="keywordtype">int</span> <a class="code" href="structbladerf__metadata.html#ade20423e91627f07e610924cb0081623">status</a>;</div><div class="line">    uint64_t curr_ts = 0;</div><div class="line">    <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> slept_ms = 0;</div><div class="line">    <span class="keywordtype">bool</span> done;</div><div class="line"></div><div class="line">    <span class="keywordflow">do</span> {</div><div class="line">        status = <a class="code" href="group___f_m_t___m_e_t_a.html#ga9b03a1b2254eab471f789627c3bde408">bladerf_get_timestamp</a>(dev, module, &amp;curr_ts);</div><div class="line">        done = (status != 0) || curr_ts &gt;= timestamp;</div><div class="line"></div><div class="line">        <span class="keywordflow">if</span> (!done) {</div><div class="line">            <span class="keywordflow">if</span> (slept_ms &gt; timeout_ms) {</div><div class="line">                done = <span class="keyword">true</span>;</div><div class="line">                status = <a class="code" href="group___r_e_t_c_o_d_e_s.html#gaf15a5facdef9565ffaae7f3e19457c10">BLADERF_ERR_TIMEOUT</a>;</div><div class="line">            } <span class="keywordflow">else</span> {</div><div class="line">                usleep(10000);</div><div class="line">                slept_ms += 10;</div><div class="line">            }</div><div class="line">        }</div><div class="line">    } <span class="keywordflow">while</span> (!done);</div><div class="line"></div><div class="line">    <span class="keywordflow">return</span> <a class="code" href="structbladerf__metadata.html#ade20423e91627f07e610924cb0081623">status</a>;</div><div class="line">}</div></div><!-- fragment --><p> <br />
 </p><h2>Scheduled Burst Example</h2>
<p>This example illustrates transmitting scheduled bursts, via a single function call.</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> sync_tx_meta_sched_example(<span class="keyword">struct</span> bladerf *dev,</div><div class="line">                             int16_t *samples, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> num_samples,</div><div class="line">                             <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> tx_count, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> samplerate,</div><div class="line">                             <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> timeout_ms)</div><div class="line">{</div><div class="line">    <span class="keywordtype">int</span> status = 0;</div><div class="line">    <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i;</div><div class="line">    <span class="keyword">struct </span><a class="code" href="structbladerf__metadata.html">bladerf_metadata</a> meta;</div><div class="line"></div><div class="line">    <span class="comment">/* 5 ms timestamp increment */</span></div><div class="line">    <span class="keyword">const</span> uint64_t ts_inc_5ms = ((uint64_t) samplerate) * 5 / 1000;</div><div class="line"></div><div class="line">    <span class="comment">/* 150 ms timestamp increment */</span></div><div class="line">    <span class="keyword">const</span> uint64_t ts_inc_150ms = ((uint64_t) samplerate) * 150 / 1000;</div><div class="line"></div><div class="line">    memset(&amp;meta, 0, <span class="keyword">sizeof</span>(meta));</div><div class="line"></div><div class="line">    <span class="comment">/* Send entire burst worth of samples in one function call */</span></div><div class="line">    meta.flags = <a class="code" href="group___f_m_t___m_e_t_a.html#ga2aef16902d542172be1b87917d89de10">BLADERF_META_FLAG_TX_BURST_START</a> |</div><div class="line">                 <a class="code" href="group___f_m_t___m_e_t_a.html#gaa9a2d61688c4b775b52a0acfed32f50a">BLADERF_META_FLAG_TX_BURST_END</a>;</div><div class="line"></div><div class="line">    <span class="comment">/* Retrieve the current timestamp so we can schedule our transmission</span></div><div class="line"><span class="comment">     * in the future. */</span></div><div class="line">    status = <a class="code" href="group___f_m_t___m_e_t_a.html#ga9b03a1b2254eab471f789627c3bde408">bladerf_get_timestamp</a>(dev, <a class="code" href="group___f_n___m_o_d_u_l_e.html#ggab12571146a3d4c5d79ac497a74b3fb5ea2b59868119a050b6f0e24631ffbb16e3">BLADERF_MODULE_TX</a>, &amp;meta.timestamp);</div><div class="line">    <span class="keywordflow">if</span> (status != 0) {</div><div class="line">        fprintf(stderr, <span class="stringliteral">&quot;Failed to get current TX timestamp: %s\n&quot;</span>,</div><div class="line">                <a class="code" href="group___r_e_t_c_o_d_e_s.html#ga689e0c91e6abb8b5575a929453e4dbcc">bladerf_strerror</a>(status));</div><div class="line">        <span class="keywordflow">return</span> <a class="code" href="structbladerf__metadata.html#ade20423e91627f07e610924cb0081623">status</a>;</div><div class="line">    } <span class="keywordflow">else</span> {</div><div class="line">        printf(<span class="stringliteral">&quot;Current TX timestamp: %016&quot;</span>PRIu64<span class="stringliteral">&quot;\n&quot;</span>, meta.timestamp);</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="comment">/* Set initial timestamp ~150 ms in the future */</span></div><div class="line">    meta.timestamp += ts_inc_150ms;</div><div class="line"></div><div class="line">    <span class="keywordflow">for</span> (i = 0; i &lt; tx_count &amp;&amp; status == 0; i++) {</div><div class="line">        <span class="comment">/* Get sample to transmit... */</span></div><div class="line">        produce_samples(samples, num_samples);</div><div class="line"></div><div class="line">        status = <a class="code" href="group___f_n___d_a_t_a___s_y_n_c.html#gac4a13bf1cb10d9a3e547b8c654268c35">bladerf_sync_tx</a>(dev, samples, num_samples, &amp;meta, timeout_ms);</div><div class="line">        <span class="keywordflow">if</span> (status != 0) {</div><div class="line">            fprintf(stderr, <span class="stringliteral">&quot;TX failed: %s\n&quot;</span>, <a class="code" href="group___r_e_t_c_o_d_e_s.html#ga689e0c91e6abb8b5575a929453e4dbcc">bladerf_strerror</a>(status));</div><div class="line">            <span class="keywordflow">return</span> <a class="code" href="structbladerf__metadata.html#ade20423e91627f07e610924cb0081623">status</a>;</div><div class="line">        } <span class="keywordflow">else</span> {</div><div class="line">            printf(<span class="stringliteral">&quot;TX&#39;d @ t=%016&quot;</span>PRIu64<span class="stringliteral">&quot;\n&quot;</span>, meta.timestamp);</div><div class="line">        }</div><div class="line"></div><div class="line">        <span class="comment">/* Schedule next burst 5 ms into the future */</span></div><div class="line">        meta.timestamp += ts_inc_5ms;</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="comment">/* Wait for samples to finish being transmitted. */</span></div><div class="line">    <span class="keywordflow">if</span> (status == 0) {</div><div class="line">        meta.timestamp += 2 * num_samples;</div><div class="line"></div><div class="line">        status = wait_for_timestamp(dev, <a class="code" href="group___f_n___m_o_d_u_l_e.html#ggab12571146a3d4c5d79ac497a74b3fb5ea2b59868119a050b6f0e24631ffbb16e3">BLADERF_MODULE_TX</a>,</div><div class="line">                                    meta.timestamp, timeout_ms);</div><div class="line"></div><div class="line">        <span class="keywordflow">if</span> (status != 0) {</div><div class="line">            fprintf(stderr, <span class="stringliteral">&quot;Failed to wait for timestamp.\n&quot;</span>);</div><div class="line">        }</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keywordflow">return</span> <a class="code" href="structbladerf__metadata.html#ade20423e91627f07e610924cb0081623">status</a>;</div><div class="line">}</div></div><!-- fragment --><p> <br />
 </p><h2>Using the TX_NOW flag</h2>
<p>In some cases, one may wish to transmit a burst immediately while using the <a class="el" href="group___f_m_t___m_e_t_a.html#gga4c61587834fd4de51a8e2d34e14a73b2a4af3974535ba338bbcecaa8d7500de03">BLADERF_FORMAT_SC16_Q11_META</a> format. As shown in the below example, this is possible by setting the <a class="el" href="group___f_m_t___m_e_t_a.html#ga1b97e995f8d20531427e316fbac3c1f9">BLADERF_META_FLAG_TX_NOW</a> flag. When using this flag the <a class="el" href="structbladerf__metadata.html#a465bef81f6478756e5443025b1f2ddfa">bladerf_metadata.timestamp</a> field is not used.</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> sync_tx_meta_now_example(<span class="keyword">struct</span> bladerf *dev, int16_t *samples,</div><div class="line">                             <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> num_samples, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> tx_count,</div><div class="line">                             <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> timeout_ms)</div><div class="line">{</div><div class="line">    <span class="keywordtype">int</span> status = 0;</div><div class="line">    <span class="keyword">struct </span><a class="code" href="structbladerf__metadata.html">bladerf_metadata</a> meta;</div><div class="line">    <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i;</div><div class="line"></div><div class="line">    memset(&amp;meta, 0, <span class="keyword">sizeof</span>(meta));</div><div class="line"></div><div class="line">    <span class="comment">/* Send entire burst worth of samples in one function call */</span></div><div class="line">    meta.flags = <a class="code" href="group___f_m_t___m_e_t_a.html#ga2aef16902d542172be1b87917d89de10">BLADERF_META_FLAG_TX_BURST_START</a> |</div><div class="line">                 <a class="code" href="group___f_m_t___m_e_t_a.html#ga1b97e995f8d20531427e316fbac3c1f9">BLADERF_META_FLAG_TX_NOW</a> |</div><div class="line">                 <a class="code" href="group___f_m_t___m_e_t_a.html#gaa9a2d61688c4b775b52a0acfed32f50a">BLADERF_META_FLAG_TX_BURST_END</a>;</div><div class="line"></div><div class="line">    <span class="keywordflow">for</span> (i = 0; i &lt; tx_count &amp;&amp; status == 0; i++) {</div><div class="line">        <span class="comment">/* Fetch or produce IQ samples...*/</span></div><div class="line">        produce_samples(samples, num_samples);</div><div class="line"></div><div class="line">        status = <a class="code" href="group___f_n___d_a_t_a___s_y_n_c.html#gac4a13bf1cb10d9a3e547b8c654268c35">bladerf_sync_tx</a>(dev, samples, num_samples, &amp;meta, timeout_ms);</div><div class="line">        <span class="keywordflow">if</span> (status != 0) {</div><div class="line">            fprintf(stderr, <span class="stringliteral">&quot;TX failed: %s\n&quot;</span>, <a class="code" href="group___r_e_t_c_o_d_e_s.html#ga689e0c91e6abb8b5575a929453e4dbcc">bladerf_strerror</a>(status));</div><div class="line">        } <span class="keywordflow">else</span> {</div><div class="line">            uint64_t curr_ts;</div><div class="line"></div><div class="line">            status = <a class="code" href="group___f_m_t___m_e_t_a.html#ga9b03a1b2254eab471f789627c3bde408">bladerf_get_timestamp</a>(dev, <a class="code" href="group___f_n___m_o_d_u_l_e.html#ggab12571146a3d4c5d79ac497a74b3fb5ea2b59868119a050b6f0e24631ffbb16e3">BLADERF_MODULE_TX</a>, &amp;curr_ts);</div><div class="line">            <span class="keywordflow">if</span> (status != 0) {</div><div class="line">                fprintf(stderr, <span class="stringliteral">&quot;Failed to get current TX timestamp: %s\n&quot;</span>,</div><div class="line">                        <a class="code" href="group___r_e_t_c_o_d_e_s.html#ga689e0c91e6abb8b5575a929453e4dbcc">bladerf_strerror</a>(status));</div><div class="line">            } <span class="keywordflow">else</span> {</div><div class="line">                printf(<span class="stringliteral">&quot;TX&#39;d at approximately t=%016&quot;</span>PRIu64<span class="stringliteral">&quot;\n&quot;</span>, curr_ts);</div><div class="line">            }</div><div class="line"></div><div class="line">            <span class="comment">/* Delay next transmission by approximately 5 ms</span></div><div class="line"><span class="comment">             *</span></div><div class="line"><span class="comment">             * This is a very imprecise, &quot;quick and dirty&quot; means to do so in</span></div><div class="line"><span class="comment">             * cases where no particular intra-burst time is required. */</span></div><div class="line">            usleep(5000);</div><div class="line">        }</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="comment">/* Wait for samples to be TX&#39;d before completing.  */</span></div><div class="line">    <span class="keywordflow">if</span> (status == 0) {</div><div class="line">        status = <a class="code" href="group___f_m_t___m_e_t_a.html#ga9b03a1b2254eab471f789627c3bde408">bladerf_get_timestamp</a>(dev, <a class="code" href="group___f_n___m_o_d_u_l_e.html#ggab12571146a3d4c5d79ac497a74b3fb5ea2b59868119a050b6f0e24631ffbb16e3">BLADERF_MODULE_TX</a>, &amp;meta.timestamp);</div><div class="line">        <span class="keywordflow">if</span> (status != 0) {</div><div class="line">            fprintf(stderr, <span class="stringliteral">&quot;Failed to get current TX timestamp: %s\n&quot;</span>,</div><div class="line">                    <a class="code" href="group___r_e_t_c_o_d_e_s.html#ga689e0c91e6abb8b5575a929453e4dbcc">bladerf_strerror</a>(status));</div><div class="line">            <span class="keywordflow">return</span> <a class="code" href="structbladerf__metadata.html#ade20423e91627f07e610924cb0081623">status</a>;</div><div class="line">        } <span class="keywordflow">else</span> {</div><div class="line">            status = wait_for_timestamp(dev, <a class="code" href="group___f_n___m_o_d_u_l_e.html#ggab12571146a3d4c5d79ac497a74b3fb5ea2b59868119a050b6f0e24631ffbb16e3">BLADERF_MODULE_TX</a>,</div><div class="line">                                        meta.timestamp + 2 * num_samples,</div><div class="line">                                        timeout_ms);</div><div class="line">            <span class="keywordflow">if</span> (status != 0) {</div><div class="line">                fprintf(stderr, <span class="stringliteral">&quot;Failed to wait for timestamp.\n&quot;</span>);</div><div class="line">            }</div><div class="line">        }</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keywordflow">return</span> <a class="code" href="structbladerf__metadata.html#ade20423e91627f07e610924cb0081623">status</a>;</div><div class="line">}</div></div><!-- fragment --><p> <br />
 </p><h2>Using the UPDATE_TIMESTAMP flag</h2>
<p>In some applications, flushing an entire buffer <a class="el" href="group___f_m_t___m_e_t_a.html#gaa9a2d61688c4b775b52a0acfed32f50a">BLADERF_META_FLAG_TX_BURST_END</a> may result in too long of a delay between bursts. As suggested earlier in this page, a user may instead manually zero pad their samples to achieve short discontinuities, or have libbladeRF do this for them using the <a class="el" href="group___f_m_t___m_e_t_a.html#gacc23fedbd8cf35143670969718ca46cb">BLADERF_META_FLAG_TX_UPDATE_TIMESTAMP</a> flag.</p>
<p>The general usage of this is: </p><ul>
<li>
<p class="startli">Set <a class="el" href="structbladerf__metadata.html#a465bef81f6478756e5443025b1f2ddfa">bladerf_metadata.timestamp</a> to the desired start of transmission, and <a class="el" href="structbladerf__metadata.html#a773b39d480759f67926cb18ae2219281">bladerf_metadata.flags</a> to <a class="el" href="group___f_m_t___m_e_t_a.html#ga2aef16902d542172be1b87917d89de10">BLADERF_META_FLAG_TX_BURST_START</a>. Call <a class="el" href="group___f_n___d_a_t_a___s_y_n_c.html#gac4a13bf1cb10d9a3e547b8c654268c35">bladerf_sync_tx()</a> with the initial samples in the burst. </p>
<p class="endli"></p>
</li>
<li>
<p class="startli"><em>Optional:</em> Call <a class="el" href="group___f_n___d_a_t_a___s_y_n_c.html#gac4a13bf1cb10d9a3e547b8c654268c35">bladerf_sync_tx()</a> with <a class="el" href="structbladerf__metadata.html#a773b39d480759f67926cb18ae2219281">bladerf_metadata.flags</a> as needed to transmit samples that are contiguous with the previous samples. <a class="el" href="structbladerf__metadata.html#a465bef81f6478756e5443025b1f2ddfa">bladerf_metadata.timestamp</a> is not used in this state. </p>
<p class="endli"></p>
</li>
<li>
<p class="startli">Call <a class="el" href="group___f_n___d_a_t_a___s_y_n_c.html#gac4a13bf1cb10d9a3e547b8c654268c35">bladerf_sync_tx()</a> with <a class="el" href="structbladerf__metadata.html#a773b39d480759f67926cb18ae2219281">bladerf_metadata.flags</a> set to <a class="el" href="group___f_m_t___m_e_t_a.html#gacc23fedbd8cf35143670969718ca46cb">BLADERF_META_FLAG_TX_UPDATE_TIMESTAMP</a> and <a class="el" href="structbladerf__metadata.html#a465bef81f6478756e5443025b1f2ddfa">bladerf_metadata.timestamp</a> set to the desired timestamp. libbladeRF will schedule the provided samples for the specified timestamp, manually zero-padding a buffer if needed. </p>
<p class="endli"></p>
</li>
<li>
<p class="startli"><em>Optional:</em> Call <a class="el" href="group___f_n___d_a_t_a___s_y_n_c.html#gac4a13bf1cb10d9a3e547b8c654268c35">bladerf_sync_tx()</a> with <a class="el" href="structbladerf__metadata.html#a773b39d480759f67926cb18ae2219281">bladerf_metadata.flags</a> as needed to transmit samples that are contiguous with the newly scheduled samples. <a class="el" href="structbladerf__metadata.html#a465bef81f6478756e5443025b1f2ddfa">bladerf_metadata.timestamp</a> is not used in this state. </p>
<p class="endli"></p>
</li>
<li>
When done transmitting, call <a class="el" href="group___f_n___d_a_t_a___s_y_n_c.html#gac4a13bf1cb10d9a3e547b8c654268c35">bladerf_sync_tx()</a> with <a class="el" href="structbladerf__metadata.html#a773b39d480759f67926cb18ae2219281">bladerf_metadata.flags</a> set to <a class="el" href="group___f_m_t___m_e_t_a.html#gaa9a2d61688c4b775b52a0acfed32f50a">BLADERF_META_FLAG_TX_BURST_END</a> and two or more zero samples. This will ensure the analog front end DACs are held at a zero value.  </li>
</ul>
<p>The above procedure is shown in the below example:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> sync_tx_meta_update_example(<span class="keyword">struct</span> bladerf *dev,</div><div class="line">                                int16_t *samples, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> num_samples,</div><div class="line">                                <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> tx_count, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> samplerate,</div><div class="line">                                <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> timeout_ms)</div><div class="line">{</div><div class="line">    <span class="keywordtype">int</span> status = 0;</div><div class="line">    <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i;</div><div class="line">    <span class="keyword">struct </span><a class="code" href="structbladerf__metadata.html">bladerf_metadata</a> meta;</div><div class="line">    int16_t zero_sample[] = { 0, 0 }; <span class="comment">/* A 0+0j sample */</span></div><div class="line"></div><div class="line">    <span class="comment">/* 5 ms timestamp increment */</span></div><div class="line">    <span class="keyword">const</span> uint64_t ts_inc_5ms = ((uint64_t) samplerate) * 5 / 1000;</div><div class="line"></div><div class="line">    <span class="comment">/* 1.25 ms timestmap increment */</span></div><div class="line">    <span class="keyword">const</span> uint64_t ts_inc_1_25ms = ((uint64_t) samplerate) * 125 / 100000;</div><div class="line"></div><div class="line">    memset(&amp;meta, 0, <span class="keyword">sizeof</span>(meta));</div><div class="line"></div><div class="line">    <span class="comment">/* The first call to bladerf_sync_tx() will start our long &quot;burst&quot; at</span></div><div class="line"><span class="comment">     * a specific timestamp.</span></div><div class="line"><span class="comment">     *</span></div><div class="line"><span class="comment">     * In successive calls, we&#39;ll break this long &quot;burst&quot; up into shorter bursts</span></div><div class="line"><span class="comment">     * by using the BLADERF_META_FLAG_TX_UPDATE_TIMESTAMP flag with new</span></div><div class="line"><span class="comment">     * timestamps.  libbladeRF will zero-pad discontinuities and/or schedule</span></div><div class="line"><span class="comment">     * timestamps for us, as needed.</span></div><div class="line"><span class="comment">     */</span></div><div class="line">    meta.flags = <a class="code" href="group___f_m_t___m_e_t_a.html#ga2aef16902d542172be1b87917d89de10">BLADERF_META_FLAG_TX_BURST_START</a>;</div><div class="line"></div><div class="line">    <span class="comment">/* Retrieve the current timestamp so we can schedule our transmission</span></div><div class="line"><span class="comment">     * in the future. */</span></div><div class="line">    status = <a class="code" href="group___f_m_t___m_e_t_a.html#ga9b03a1b2254eab471f789627c3bde408">bladerf_get_timestamp</a>(dev, <a class="code" href="group___f_n___m_o_d_u_l_e.html#ggab12571146a3d4c5d79ac497a74b3fb5ea2b59868119a050b6f0e24631ffbb16e3">BLADERF_MODULE_TX</a>, &amp;meta.timestamp);</div><div class="line">    <span class="keywordflow">if</span> (status != 0) {</div><div class="line">        fprintf(stderr, <span class="stringliteral">&quot;Failed to get current TX timestamp: %s\n&quot;</span>,</div><div class="line">                <a class="code" href="group___r_e_t_c_o_d_e_s.html#ga689e0c91e6abb8b5575a929453e4dbcc">bladerf_strerror</a>(status));</div><div class="line">        <span class="keywordflow">return</span> <a class="code" href="structbladerf__metadata.html#ade20423e91627f07e610924cb0081623">status</a>;</div><div class="line">    } <span class="keywordflow">else</span> {</div><div class="line">        printf(<span class="stringliteral">&quot;Current TX timestamp: %016&quot;</span>PRIu64<span class="stringliteral">&quot;\n&quot;</span>, meta.timestamp);</div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="comment">/* Start 5 ms in the future */</span></div><div class="line">    meta.timestamp += ts_inc_5ms;</div><div class="line"></div><div class="line">    <span class="keywordflow">for</span> (i = 0; i &lt; tx_count &amp;&amp; status == 0; i++) {</div><div class="line">        <span class="comment">/* Get sample to transmit... */</span></div><div class="line">        produce_samples(samples, num_samples);</div><div class="line"></div><div class="line">        status = <a class="code" href="group___f_n___d_a_t_a___s_y_n_c.html#gac4a13bf1cb10d9a3e547b8c654268c35">bladerf_sync_tx</a>(dev, samples, num_samples, &amp;meta, timeout_ms);</div><div class="line">        <span class="keywordflow">if</span> (status != 0) {</div><div class="line">            fprintf(stderr, <span class="stringliteral">&quot;TX failed: %s\n&quot;</span>, <a class="code" href="group___r_e_t_c_o_d_e_s.html#ga689e0c91e6abb8b5575a929453e4dbcc">bladerf_strerror</a>(status));</div><div class="line">            <span class="keywordflow">return</span> <a class="code" href="structbladerf__metadata.html#ade20423e91627f07e610924cb0081623">status</a>;</div><div class="line">        } <span class="keywordflow">else</span> {</div><div class="line">            printf(<span class="stringliteral">&quot;TX&#39;d @ t=%016&quot;</span>PRIu64<span class="stringliteral">&quot;\n&quot;</span>, meta.timestamp);</div><div class="line">        }</div><div class="line"></div><div class="line">        <span class="comment">/* Instruct bladerf_sync_tx() to position samples within this burst at</span></div><div class="line"><span class="comment">         * the specified timestamp. 0+0j will be transmitted up until that</span></div><div class="line"><span class="comment">         * point. */</span></div><div class="line">        meta.flags = <a class="code" href="group___f_m_t___m_e_t_a.html#gacc23fedbd8cf35143670969718ca46cb">BLADERF_META_FLAG_TX_UPDATE_TIMESTAMP</a>;</div><div class="line"></div><div class="line">        <span class="comment">/* Schedule samples to be transmitted 1.25 ms after the completion of</span></div><div class="line"><span class="comment">         * the previous burst */</span></div><div class="line">        meta.timestamp += num_samples + ts_inc_1_25ms;</div><div class="line"></div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="comment">/* For simplicity, we use a single zero sample to end the burst and request</span></div><div class="line"><span class="comment">     * that all pending samples be flushed to the hardware. */</span></div><div class="line">    meta.flags = <a class="code" href="group___f_m_t___m_e_t_a.html#gaa9a2d61688c4b775b52a0acfed32f50a">BLADERF_META_FLAG_TX_BURST_END</a>;</div><div class="line">    status = <a class="code" href="group___f_n___d_a_t_a___s_y_n_c.html#gac4a13bf1cb10d9a3e547b8c654268c35">bladerf_sync_tx</a>(dev, zero_sample, 1, &amp;meta, timeout_ms);</div><div class="line">    meta.timestamp++;</div><div class="line"></div><div class="line">    <span class="comment">/* Wait for samples to finish being transmitted. */</span></div><div class="line">    <span class="keywordflow">if</span> (status == 0) {</div><div class="line">        meta.timestamp += 2 * num_samples;</div><div class="line"></div><div class="line">        status = wait_for_timestamp(dev, <a class="code" href="group___f_n___m_o_d_u_l_e.html#ggab12571146a3d4c5d79ac497a74b3fb5ea2b59868119a050b6f0e24631ffbb16e3">BLADERF_MODULE_TX</a>,</div><div class="line">                                    meta.timestamp, timeout_ms);</div><div class="line"></div><div class="line">        <span class="keywordflow">if</span> (status != 0) {</div><div class="line">            fprintf(stderr, <span class="stringliteral">&quot;Failed to wait for timestamp.\n&quot;</span>);</div><div class="line">        }</div><div class="line">    } <span class="keywordflow">else</span> {</div><div class="line">        fprintf(stderr, <span class="stringliteral">&quot;Failed to complete burst: %s\n&quot;</span>,</div><div class="line">                <a class="code" href="group___r_e_t_c_o_d_e_s.html#ga689e0c91e6abb8b5575a929453e4dbcc">bladerf_strerror</a>(status));</div><div class="line">    }</div><div class="line"></div><div class="line"></div><div class="line">    <span class="keywordflow">return</span> <a class="code" href="structbladerf__metadata.html#ade20423e91627f07e610924cb0081623">status</a>;</div><div class="line">}</div></div><!-- fragment --></div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Wed Jun 29 2016 16:51:01 for libbladeRF by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.11
</small></address>
</body>
</html>