commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r6318 - gnuradio/branches/developers/gnychis/inband/us


From: gnychis
Subject: [Commit-gnuradio] r6318 - gnuradio/branches/developers/gnychis/inband/usrp/host/apps
Date: Wed, 5 Sep 2007 12:38:39 -0600 (MDT)

Author: gnychis
Date: 2007-09-05 12:38:39 -0600 (Wed, 05 Sep 2007)
New Revision: 6318

Modified:
   
gnuradio/branches/developers/gnychis/inband/usrp/host/apps/test_usrp_inband_underrun.cc
Log:
Test program for underruns done, ready to play with values for actual testing


Modified: 
gnuradio/branches/developers/gnychis/inband/usrp/host/apps/test_usrp_inband_underrun.cc
===================================================================
--- 
gnuradio/branches/developers/gnychis/inband/usrp/host/apps/test_usrp_inband_underrun.cc
     2007-09-05 17:32:13 UTC (rev 6317)
+++ 
gnuradio/branches/developers/gnychis/inband/usrp/host/apps/test_usrp_inband_underrun.cc
     2007-09-05 18:38:39 UTC (rev 6318)
@@ -38,6 +38,7 @@
 #include <string.h>
 #include <sys/time.h>
 #include <iostream>
+#include <ui_nco.h>
 
 // Include the symbols needed for communication with USRP server
 #include <symbols_usrp_server_cs.h>
@@ -70,11 +71,24 @@
     ALLOCATING_CHANNELS,
     WRITE_REGISTER,
     READ_REGISTER,
+    TRANSMITTING,
     CLOSING_CHANNELS,
     CLOSING_USRP,
   };
   state_t d_state;
+  
+  long         d_nsamples_to_send;
+  long         d_nsamples_xmitted;
+  long         d_nframes_xmitted;
+  long         d_samples_per_frame;
+  bool         d_done_sending;
 
+  // for generating sine wave output
+  ui_nco<float,float>  d_nco;
+  double               d_amplitude;
+
+  long d_n_underruns;
+
  public:
   test_usrp_inband_underrun(mb_runtime *runtime, const std::string 
&instance_name, pmt_t user_arg);
   ~test_usrp_inband_underrun();
@@ -89,7 +103,11 @@
   void closing_channels();
   void closing_usrp();
   void enter_receiving();
+  void enter_transmitting();
   void build_and_send_ping();
+  void build_and_send_next_frame();
+  void handle_xmit_response(pmt_t handle);
+  void handle_recv_response(pmt_t dict);
 };
 
 
@@ -110,7 +128,15 @@
   d_tx_chan(PMT_NIL),
   d_rx_chan(PMT_NIL),
   d_which_usrp(pmt_from_long(0)),
-  d_state(INIT)
+  d_state(INIT),
+  d_nsamples_to_send((long) 5e6),
+  d_nsamples_xmitted(0),
+  d_nframes_xmitted(0),
+  d_samples_per_frame(d_nsamples_to_send),     // full packet
+
+  d_done_sending(false),
+  d_amplitude(16384),
+  d_n_underruns(0)
 {
   
   // A dictionary is used to pass parameters to the USRP
@@ -140,6 +166,11 @@
   connect("self", "rx0", "server", "rx0");
   connect("self", "cs", "server", "cs");
 
+  // initialize NCO
+  double freq = 100e3;
+  int interp = 32;                         // 32 -> 4MS/s
+  double sample_rate = 128e6 / interp; 
+  d_nco.set_freq(2*M_PI * freq/sample_rate);
 }
 
 test_usrp_inband_underrun::~test_usrp_inband_underrun()
@@ -164,6 +195,7 @@
 
   pmt_t handle = PMT_F;
   pmt_t status = PMT_F;
+  pmt_t dict = PMT_NIL;
   std::string error_msg;
 
   // Dispatch based on state
@@ -210,13 +242,13 @@
           d_tx_chan = pmt_nth(2, data);
 
           if(verbose)
-            std::cout << "[TEST_USRP_INBAND_PING] Received TX allocation"
+            std::cout << "[TEST_USRP_INBAND_UNDERRUN] Received TX allocation"
                       << " on channel " << d_tx_chan << std::endl;
 
           // If the RX has also been allocated already, we can continue
           if(!pmt_eqv(d_rx_chan, PMT_NIL)) {
             enter_receiving();
-            write_register();
+            enter_transmitting();
           }
 
           return;
@@ -239,13 +271,13 @@
           d_rx_chan = pmt_nth(2, data);
 
           if(verbose)
-            std::cout << "[TEST_USRP_INBAND_PING] Received RX allocation"
+            std::cout << "[TEST_USRP_INBAND_UNDERRUN] Received RX allocation"
                       << " on channel " << d_rx_chan << std::endl;
 
           // If the TX has also been allocated already, we can continue
           if(!pmt_eqv(d_tx_chan, PMT_NIL)) {
             enter_receiving();
-            write_register();
+            enter_transmitting();
           }
 
           return;
@@ -258,63 +290,135 @@
 
       goto unhandled;
 
-    //-------------------------- WRITE REGISTER ----------------------------//
-    // In the write register state, we do not expect to receive any messages
-    // since the write does not directly generate a response until the USRP
-    // responds.
     case WRITE_REGISTER:
       goto unhandled;
 
-    //-------------------------- READ REGISTER ----------------------------//
-    // In the read register state, we only expect a read register response back
-    // that has the value we expect to have in it.  We read the response, 
ensure
-    // that the read was successful and display the register value.
     case READ_REGISTER:
+      goto unhandled;
 
-      if(pmt_eq(event, s_response_from_control_channel)
+    //-------------------------- TRANSMITTING ----------------------------//
+    // In the transmit state we count the number of underruns received and
+    // ballpark the number with an expected count (something >1 for starters)
+    case TRANSMITTING:
+      
+      // Check that the transmits are OK
+      if (pmt_eq(event, s_response_xmit_raw_frame)){
+        handle = pmt_nth(0, data);
+        status = pmt_nth(1, data);
+
+        if (pmt_eq(status, PMT_T)){
+          handle_xmit_response(handle);
+          return;
+        }
+        else {
+          error_msg = "bad response-xmit-raw-frame:";
+          goto bail;
+        }
+      }
+
+      // Check the recv sample responses for underruns and count
+      if(pmt_eq(event, s_response_recv_raw_samples)) {
+        handle = pmt_nth(0, data);
+        status = pmt_nth(1, data);
+        dict   = pmt_nth(4, data);
+
+        if(pmt_eq(status, PMT_T)) {
+          handle_recv_response(dict);
+          return;
+        }
+        else {
+          error_msg = "error while receiving samples:";
+          goto bail;
+        }
+      }
+
+      goto unhandled;
+
+    //------------------------- CLOSING CHANNELS ----------------------------//
+    // Check deallocation responses, once the TX and RX channels are both
+    // deallocated then we close the USRP.
+    case CLOSING_CHANNELS:
+      
+      if (pmt_eq(event, s_response_deallocate_channel)
           && pmt_eq(d_tx->port_symbol(), port_id))
       {
         status = pmt_nth(1, data);
 
-        // If the read was successful, we extract the subpacket information
+        // If successful, set the port to NIL
         if(pmt_eq(status, PMT_T)) {
-          
-          pmt_t subp = pmt_nth(2, data);      // subpacket should be the read 
reg reply
+          d_tx_chan = PMT_NIL;
 
-          pmt_t subp_sig  = pmt_nth(0, subp);
-          pmt_t subp_data = pmt_nth(1, subp);
+          if(verbose)
+            std::cout << "[TEST_USRP_INBAND_UNDERRUN] Received TX 
deallocation\n";
 
-          if(!pmt_eqv(subp_sig, s_op_read_reg_reply)) {
-            error_msg = "received improper subpacket when expecting reg 
reply.";
-            goto bail;
-          }
+          // If the RX is also deallocated, we can close the USRP
+          if(pmt_eq(d_rx_chan, PMT_NIL)) 
+            closing_usrp();
 
-          pmt_t rid     = pmt_nth(0, subp_data);
-          pmt_t reg_num = pmt_nth(1, subp_data);
-          pmt_t reg_val = pmt_nth(2, subp_data);
+          return;
 
+        } else {
+
+          error_msg = "failed to deallocate TX channel:";
+          goto bail;
+
+        }
+      }
+
+      if (pmt_eq(event, s_response_deallocate_channel)
+          && pmt_eq(d_rx->port_symbol(), port_id))
+      {
+        status = pmt_nth(1, data);
+
+        // If successful, set the port to NIL
+        if(pmt_eq(status, PMT_T)) {
+          d_rx_chan = PMT_NIL;
+
           if(verbose)
-            std::cout << "[TEST_USRP_INBAND_REGISTERS] Received read reg reply 
"
-                      << "("
-                      << "RID: " << rid << ", " 
-                      << "Reg: " << reg_num << ", "
-                      << "Val: " << reg_val
-                      << ")\n";
-          
-          // read_register();  FIX ME STATE TRANSITION
+            std::cout << "[TEST_USRP_INBAND_UNDERRUN] Received RX 
deallocation\n";
+
+          // If the TX is also deallocated, we can close the USRP
+          if(pmt_eq(d_tx_chan, PMT_NIL)) 
+            closing_usrp();
+
           return;
 
-        } else {  // bail on unsuccessful write
-          error_msg = "failed to write to register.";
+        } else {
+          
+          error_msg = "failed to deallocate RX channel:";
           goto bail;
+
         }
       }
-      goto unhandled;
 
-    case CLOSING_CHANNELS:
       goto unhandled;
 
+    //--------------------------- CLOSING USRP ------------------------------//
+    // Once we have received a successful USRP close response, we shutdown all
+    // mblocks and exit.
     case CLOSING_USRP:
+      
+      if (pmt_eq(event, s_response_close)) {
+        
+        status = pmt_nth(1, data);
+
+        if(pmt_eq(status, PMT_T)) {
+
+          if(verbose)
+            std::cout << "[TEST_USRP_INBAND_UNDERRUN] Successfully closed 
USRP\n";
+
+          std::cout << "\nUnderruns: " << d_n_underruns << std::endl;
+
+          shutdown_all(PMT_T);
+          return;
+
+        } else {
+
+          error_msg = "failed to close USRP:";
+          goto bail;
+        }
+      }
+
       goto unhandled;
 
     case INIT:
@@ -331,7 +435,7 @@
 
  // Received an unhandled message for a specific state
  unhandled:
-  if(verbose && !pmt_eq(event, s_response_recv_raw_samples))
+  if(verbose && !pmt_eq(event, pmt_intern("%shutdown")))
     std::cout << "test_usrp_inband_tx: unhandled msg: " << msg
               << "in state "<< d_state << std::endl;
 
@@ -345,7 +449,7 @@
 {
 
   if(verbose)
-    std::cout << "[TEST_USRP_INBAND_PING] Opening USRP " 
+    std::cout << "[TEST_USRP_INBAND_UNDERRUN] Opening USRP " 
               << d_which_usrp << std::endl;
 
   d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, d_which_usrp));
@@ -400,7 +504,7 @@
                                                     pmt_list2(pmt_from_long(0),
                                                               
pmt_from_long(0))))));
 
-  std::cout << "[TEST_USRP_INBAND_CS] Ping sent" << std::endl;
+  std::cout << "[TEST_USRP_INBAND_UNDERRUN] Ping sent" << std::endl;
 }
 
 // After writing to the register, we want to read the value back and ensure 
that
@@ -420,7 +524,7 @@
                                       pmt_from_long(0),   // rid 
                                       pmt_from_long(reg))))));
   if(verbose)
-    std::cout << "[TEST_USRP_INBAND_REGISTERS] Reading from register " 
+    std::cout << "[TEST_USRP_INBAND_UNDERRUN] Reading from register " 
               << reg << std::endl;
 }
 
@@ -433,4 +537,118 @@
                        d_rx_chan));
 }
 
+void
+test_usrp_inband_underrun::enter_transmitting()
+{
+  d_state = TRANSMITTING;
+  d_nsamples_xmitted = 0;
+
+  if(verbose)
+    std::cout << "[TEST_USRP_INBAND_UNDERRUN] Entering transmit state...\n";
+  
+  build_and_send_next_frame(); // fire off 4 to start pipeline
+  build_and_send_next_frame();
+  build_and_send_next_frame();
+  build_and_send_next_frame();
+}
+
+void
+test_usrp_inband_underrun::build_and_send_next_frame()
+{
+
+  long nsamples_this_frame =
+    std::min(d_nsamples_to_send - d_nsamples_xmitted,
+            d_samples_per_frame);
+
+  if (nsamples_this_frame == 0){
+    d_done_sending = true;
+    return;
+  }
+    
+  size_t nshorts = 2 * nsamples_this_frame;    // 16-bit I & Q
+  pmt_t uvec = pmt_make_s16vector(nshorts, 0);
+  size_t ignore;
+  int16_t *samples = pmt_s16vector_writeable_elements(uvec, ignore);
+
+  // fill in the complex sinusoid
+
+  for (int i = 0; i < nsamples_this_frame; i++){
+
+    if (1){
+      gr_complex s;
+      d_nco.sincos(&s, 1, d_amplitude);
+      // write 16-bit i & q
+      samples[2*i] =   (int16_t) s.real();
+      samples[2*i+1] = (int16_t) s.imag();
+    }
+    else {
+      gr_complex s(d_amplitude, d_amplitude);
+
+      // write 16-bit i & q
+      samples[2*i] =   (int16_t) s.real();
+      samples[2*i+1] = (int16_t) s.imag();
+    }
+  }
+
+  pmt_t timestamp = pmt_from_long(0xffffffff); // NOW
+  d_tx->send(s_cmd_xmit_raw_frame,
+            pmt_list4(pmt_from_long(d_nframes_xmitted),  // invocation-handle
+                      d_tx_chan,                         // channel
+                      uvec,                              // the samples
+                      timestamp));
+
+  d_nsamples_xmitted += nsamples_this_frame;
+  d_nframes_xmitted++;
+
+  if(verbose && 0)
+    std::cout << "[TEST_USRP_INBAND_TX] Transmitted frame\n";
+}
+
+void
+test_usrp_inband_underrun::handle_xmit_response(pmt_t handle)
+{
+  if (d_done_sending &&
+      pmt_to_long(handle) == (d_nframes_xmitted - 1)){
+    // We're done sending and have received all responses
+    closing_channels();
+  }
+
+  build_and_send_next_frame();
+}
+
+void
+test_usrp_inband_underrun::handle_recv_response(pmt_t dict)
+{
+  if(!pmt_is_dict(dict)) {
+    std::cout << "[TEST_USRP_INBAND_UNDERRUN] Recv samples dictionary is 
improper\n";
+    return;
+  }
+
+  // Read the TX interpolations
+  if(pmt_t underrun = pmt_dict_ref(dict, 
+                                  pmt_intern("underrun"), 
+                                  PMT_NIL)) {
+    if(pmt_eqv(underrun, PMT_T)) 
+      d_n_underruns++;
+  }
+  
+}
+
+void
+test_usrp_inband_underrun::closing_channels()
+{
+  d_state = CLOSING_CHANNELS;
+
+  d_tx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_tx_chan));
+  d_rx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_rx_chan));
+}
+
+void
+test_usrp_inband_underrun::closing_usrp()
+{
+  d_state = CLOSING_USRP;
+
+  d_cs->send(s_cmd_close, pmt_list1(PMT_NIL));
+}
+
 REGISTER_MBLOCK_CLASS(test_usrp_inband_underrun);





reply via email to

[Prev in Thread] Current Thread [Next in Thread]