commit-gnuradio
[Top][All Lists]
Advanced

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

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


From: gnychis
Subject: [Commit-gnuradio] r4965 - gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband
Date: Wed, 11 Apr 2007 23:14:57 -0600 (MDT)

Author: gnychis
Date: 2007-04-11 23:14:57 -0600 (Wed, 11 Apr 2007)
New Revision: 4965

Modified:
   
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_server.cc
   
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_server.h
Log:
initial code for handling raw frame transmissions, breaking each frame down in 
to USB packets and setting the appropriate header fields



Modified: 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_server.cc
===================================================================
--- 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_server.cc 
    2007-04-12 05:06:09 UTC (rev 4964)
+++ 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_server.cc 
    2007-04-12 05:14:57 UTC (rev 4965)
@@ -25,6 +25,7 @@
 #include <usrp_server.h>
 #include <iostream>
 #include <usrp_inband_usb_packet.h>
+#include <vector>
 
 
 // FIXME We should machine generate these by a simple preprocessor run over 
this file
@@ -75,12 +76,12 @@
 
   // Initialize capacity on each channel to 0 and to no owner
   for(int chan=0; chan < d_in_tx_chan; chan++) {
-    chaninfo_tx[chan].d_assigned_capacity = 0;
-    chaninfo_tx[chan].d_owner = PMT_NIL;
+    d_chaninfo_tx[chan].assigned_capacity = 0;
+    d_chaninfo_tx[chan].owner = PMT_NIL;
   }
   for(int chan=0; chan < d_in_rx_chan; chan++) {
-    chaninfo_rx[chan].d_assigned_capacity = 0;
-    chaninfo_rx[chan].d_owner = PMT_NIL;
+    d_chaninfo_rx[chan].assigned_capacity = 0;
+    d_chaninfo_rx[chan].owner = PMT_NIL;
   }
 }
 
@@ -146,15 +147,15 @@
 
   if (pmt_eq(event, s_cmd_deallocate_channel)) {
     reply_data = handle_cmd_deallocate_channel(port_id, data);
-    d_cs->send(s_response_allocate_channel, reply_data);
+    d_cs->send(s_response_deallocate_channel, reply_data);
     return;
   }
-//    
-//  if (pmt_eq(event, s_cmd_xmit_raw_frame)){
-//    reply_data = handle_cmd_xmit_raw_frame(data);
-//    d_cs->send(s_response_allocate_channel, reply_data);
-//    return;
-//  }
+    
+  if (pmt_eq(event, s_cmd_xmit_raw_frame)){
+    reply_data = handle_cmd_xmit_raw_frame(data);
+    d_cs->send(s_response_xmit_raw_frame, reply_data);
+    return;
+  }
 
  unhandled:
   std::cout << "unhandled msg: " << msg << std::endl;
@@ -163,19 +164,23 @@
 // Return -1 if it is not an RX port, or an index
 long usrp_server::is_tx_port(pmt_t port_id) {
 
-  for(int port=0; port < D_MAX_PORTS; port++) 
-    if(pmt_eq(pmt_intern(d_tx.at(port)->port_name()), port_id))
-      return port;
+  std::vector<mb_port_sptr>::iterator tx;
 
+  for(tx = d_tx.begin(); tx != d_tx.end(); tx++) 
+    if(pmt_eq((*tx)->port_symbol(), port_id))
+      return std::distance(d_tx.begin(), tx);
+
   return -1;
 }
 
 // Return -1 if it is not an RX port, or an index
 long usrp_server::is_rx_port(pmt_t port_id) {
+  
+  std::vector<mb_port_sptr>::iterator rx;
 
-  for(int port=0; port < D_MAX_PORTS; port++) 
-    if(pmt_eq(pmt_intern(d_rx.at(port)->port_name()), port_id))
-      return port;
+  for(rx = d_rx.begin(); rx != d_rx.end(); rx++) 
+    if(pmt_eq((*rx)->port_symbol(), port_id))
+      return std::distance(d_rx.begin(), rx);
 
   return -1;
 }
@@ -198,10 +203,10 @@
   long capacity = 0;
 
   for(int chan=0; chan < d_in_tx_chan; chan++) 
-    capacity += chaninfo_tx[chan].d_assigned_capacity;
+    capacity += d_chaninfo_tx[chan].assigned_capacity;
 
   for(int chan=0; chan < d_in_rx_chan; chan++)
-    capacity += chaninfo_rx[chan].d_assigned_capacity;
+    capacity += d_chaninfo_rx[chan].assigned_capacity;
 
   return capacity;
 }
@@ -226,13 +231,13 @@
 
     // Find a free channel
     for(chan=0; chan < d_in_tx_chan; chan++) 
-      if(chaninfo_tx[chan].d_owner == PMT_NIL) 
+      if(d_chaninfo_tx[chan].owner == PMT_NIL) 
         break;
 
     // If we found a free channel, set the owner of the channel and assigned 
capacity
     if(chan < d_in_tx_chan) {
-      chaninfo_tx[chan].d_owner = port_id;
-      chaninfo_tx[chan].d_assigned_capacity = assigned_capacity;
+      d_chaninfo_tx[chan].owner = port_id;
+      d_chaninfo_tx[chan].assigned_capacity = assigned_capacity;
       return pmt_list3(invocation_handle, PMT_T, pmt_from_long(chan));
     }
 
@@ -242,12 +247,12 @@
   if(port_type == D_PORT_TYPE_RX) {
 
     for(chan=0; chan < d_in_tx_chan; chan++) 
-      if(chaninfo_tx[chan].d_owner == PMT_NIL) 
+      if(d_chaninfo_tx[chan].owner == PMT_NIL) 
         break;
 
     if(chan < d_in_tx_chan) {
-      chaninfo_tx[chan].d_owner = port_id;
-      chaninfo_tx[chan].d_assigned_capacity = assigned_capacity;
+      d_chaninfo_tx[chan].owner = port_id;
+      d_chaninfo_tx[chan].assigned_capacity = assigned_capacity;
       return pmt_list3(invocation_handle, PMT_T, pmt_from_long(chan));
     }
 
@@ -272,11 +277,11 @@
     if(channel >= d_in_tx_chan) 
       return pmt_list2(invocation_handle, PMT_F);   // not a legit channel 
number
 
-    if(chaninfo_tx[channel].d_owner != port_id) 
+    if(d_chaninfo_tx[channel].owner != port_id) 
       return pmt_list2(invocation_handle, PMT_F);   // not the owner of the 
port
 
-    chaninfo_tx[channel].d_assigned_capacity = 0;
-    chaninfo_tx[channel].d_owner = PMT_NIL;
+    d_chaninfo_tx[channel].assigned_capacity = 0;
+    d_chaninfo_tx[channel].owner = PMT_NIL;
 
     return pmt_list2(invocation_handle, PMT_T);
   }
@@ -286,38 +291,74 @@
     if(channel >= d_in_rx_chan) 
       return pmt_list2(invocation_handle, PMT_F);   // not a legit channel 
number
 
-    if(chaninfo_rx[channel].d_owner != port_id) 
+    if(d_chaninfo_rx[channel].owner != port_id) 
       return pmt_list2(invocation_handle, PMT_F);   // not the owner of the 
port
 
-    chaninfo_rx[channel].d_assigned_capacity = 0;
-    chaninfo_rx[channel].d_owner = PMT_NIL;
+    d_chaninfo_rx[channel].assigned_capacity = 0;
+    d_chaninfo_rx[channel].owner = PMT_NIL;
 
     return pmt_list2(invocation_handle, PMT_T);
   }
 
 }
 
-//  
-//pmt_t usrp_server::handle_cmd_xmit_raw_frame(pmt_t data) {
-//  pmt_t invocation_handle = pmt_nth(0, data);
-//  long channel = pmt_to_long(pmt_nth(1, data));  // the channel to deallocate
-//
-//  // Read the samples, which are in a uniform numeric vector and find the 
number of samples
-//  size_t num_samples;
-//  uint32_t *samples = (uint32_t *) pmt_uniform_vector_elements(pmt_nth(2, 
data), num_samples);
-//  long payload_len = num_samples * sizeof(uint32_t);
-//
-//  long timestamp = pmt_to_long(pmt_nth(3, data));       // the timestamp to 
send the samples to the D/A converter
-// 
-//  usrp_inband_usb_packet usb_packet;                    // lets make a 
packet!
-//  
-//  // Set the header of the packet... what should 'tag' be set to here?
-//  usb_packet.set_header(0, channel, 0, payload_len);
-//  usb_packet.set_timestamp(timestamp);
-//  memcpy(usb_packet.payload(), samples, payload_len);
-//
-//  // interface with the USRP to send the USB packet
-//  
-//  return pmt_list2(invocation_handle, PMT_T);
-//}
+// Given the data, and a packet number, determine the payload length for the
+// given packet number and return it.
+long usrp_server::payload_len(long pkt_number, size_t samples_size) {
 
+  long max_payload_len = (USB_PKT_SIZE-2*sizeof(uint32_t));
+  long last_packet = (samples_size / max_payload_len) - 1;  // packets start 
at 0, hence '- 1'
+  long last_pkt_size = samples_size % max_payload_len;
+
+  if(pkt_number == last_packet)
+    return last_pkt_size;
+  else
+    return max_payload_len;
+}
+  
+pmt_t usrp_server::handle_cmd_xmit_raw_frame(pmt_t data) {
+
+  size_t samples_size;                    // this is in bytes, not number of 
samples
+  long num_packets, packets_transfered;
+  usrp_inband_usb_packet *usb_pkt;
+  long max_payload_len = (USB_PKT_SIZE-2*sizeof(uint32_t));
+  long curr_payload_len;
+
+  pmt_t invocation_handle = pmt_nth(0, data);
+  long channel = pmt_to_long(pmt_nth(1, data));
+  const void *samples = pmt_uniform_vector_elements(pmt_nth(2, data), 
samples_size);
+  long timestamp = pmt_to_long(pmt_nth(3, data));
+
+  // The number of packets we need to create is the size of the samples
+  // divided by the size of the payload of our USB packets.  This memory
+  // is then allocated contiguously so that we can burst nicely on the bus.
+  num_packets = samples_size / max_payload_len + 1;   // always at least 1 
packet
+  pmt_t packets = pmt_make_u8vector(USB_PKT_SIZE * num_packets, 0);
+
+  // The initial packet has the timestamp set with flags the other packets 
don't have set. 
+  usb_pkt = (usrp_inband_usb_packet *) pmt_u8vector_ref(packets, 0);
+  curr_payload_len = payload_len(0, samples_size);
+  usb_pkt->set_header(0, channel, 0, curr_payload_len);
+  usb_pkt->start_of_burst();
+  usb_pkt->set_timestamp(timestamp);
+  memcpy(usb_pkt->payload(), samples, curr_payload_len);
+
+  // The rest of the packets have a timestamp of 'now' and no flags set.
+  for(int pkt = 1; pkt < num_packets; pkt++) {
+    usb_pkt = (usrp_inband_usb_packet *) pmt_u8vector_ref(packets, 
USB_PKT_SIZE * pkt);
+    curr_payload_len = payload_len(pkt, samples_size);
+    usb_pkt->set_header(0, channel, 0, curr_payload_len);
+    usb_pkt->set_timestamp(0xffffffff);
+    memcpy(usb_pkt->payload(), (uint8_t *)samples+(USB_PKT_SIZE * pkt), 
curr_payload_len);
+  }
+
+  // Set the last packet's end of burst flag, even if the first packet is the 
last
+  ((usrp_inband_usb_packet *)pmt_u8vector_ref(packets, 
num_packets-1))->end_of_burst();
+
+  // interface with the USRP to send the USB packet, since the memory is
+  // contiguous, this should be a serious of memory copies to the bus, each 
being
+  // USB_PKT_SIZE * MAX_PACKET_BURST bytes worth of data (given a full burst)
+  
+  return pmt_list2(invocation_handle, PMT_T);
+}
+

Modified: 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_server.h
===================================================================
--- 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_server.h  
    2007-04-12 05:06:09 UTC (rev 4964)
+++ 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_server.h  
    2007-04-12 05:14:57 UTC (rev 4965)
@@ -44,12 +44,12 @@
   long d_in_rx_chan;
 
   struct channel_info {
-    long d_assigned_capacity;  // the capacity currently assignedby the channel
-    pmt_t d_owner;              // port ID of the owner of the channel
+    long assigned_capacity;  // the capacity currently assignedby the channel
+    pmt_t owner;              // port ID of the owner of the channel
   };
 
-  struct channel_info chaninfo_tx[D_MAX_CHANNELS];
-  struct channel_info chaninfo_rx[D_MAX_CHANNELS];
+  struct channel_info d_chaninfo_tx[D_MAX_CHANNELS];
+  struct channel_info d_chaninfo_rx[D_MAX_CHANNELS];
 
 public:
   usrp_server(mb_runtime *rt, const std::string &instance_name, pmt_t 
user_arg);
@@ -66,6 +66,7 @@
   long is_tx_port(pmt_t port_id);
   long current_capacity_allocation();
   long get_port_type(pmt_t port_id);
+  long payload_len(long pkt_number, size_t samples_size);
 };
 
 #endif /* INCLUDED_USRP_SERVER_H */





reply via email to

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