commit-gnuradio
[Top][All Lists]
Advanced

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

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


From: gnychis
Subject: [Commit-gnuradio] r4979 - gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband
Date: Fri, 13 Apr 2007 00:40:19 -0600 (MDT)

Author: gnychis
Date: 2007-04-13 00:40:18 -0600 (Fri, 13 Apr 2007)
New Revision: 4979

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:
sending responses on the correct ports now

handling creating of USB packets cleaner and hopefully properly, need to trace 
the code on some corner cases to be sure

setting flags in the packet headers instead of just reading them

cleaned up loops around finding the port in our port vector and returning its 
index


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-13 06:24:09 UTC (rev 4978)
+++ 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_server.cc 
    2007-04-13 06:40:18 UTC (rev 4979)
@@ -27,6 +27,7 @@
 #include <usrp_inband_usb_packet.h>
 #include <vector>
 
+typedef usrp_inband_usb_packet transport_pkt;   // makes conversion to gigabit 
easy
 
 // FIXME We should machine generate these by a simple preprocessor run over 
this file
 //
@@ -64,22 +65,22 @@
   //
   // (if/when we do replicated ports, these will be replaced by a
   //  single replicated port)
-  for(int port=0; port < D_MAX_PORTS; port++) {
+  for(int port=0; port < N_PORTS; port++) {
     d_tx.push_back(define_port("rx"+port, "usrp-tx", true, mb_port::EXTERNAL));
     d_rx.push_back(define_port("tx"+port, "usrp-rx", true, mb_port::EXTERNAL));
   }
 
   // FIXME ... initializing to 2 channels on each for now, eventually we should
   // query the FPGA to get these values
-  d_in_tx_chan = 2;
-  d_in_rx_chan = 2;
+  d_ntx_chan = 2;
+  d_nrx_chan = 2;
 
   // Initialize capacity on each channel to 0 and to no owner
-  for(int chan=0; chan < d_in_tx_chan; chan++) {
+  for(int chan=0; chan < d_ntx_chan; chan++) {
     d_chaninfo_tx[chan].assigned_capacity = 0;
     d_chaninfo_tx[chan].owner = PMT_NIL;
   }
-  for(int chan=0; chan < d_in_rx_chan; chan++) {
+  for(int chan=0; chan < d_nrx_chan; chan++) {
     d_chaninfo_rx[chan].assigned_capacity = 0;
     d_chaninfo_rx[chan].owner = PMT_NIL;
   }
@@ -140,20 +141,17 @@
   }
 
   if (pmt_eq(event, s_cmd_allocate_channel)){
-    reply_data = handle_cmd_allocate_channel(port_id, data);
-    d_cs->send(s_response_allocate_channel, reply_data);
+    handle_cmd_allocate_channel(port_id, data);
     return;
   }
 
   if (pmt_eq(event, s_cmd_deallocate_channel)) {
-    reply_data = handle_cmd_deallocate_channel(port_id, data);
-    d_cs->send(s_response_deallocate_channel, reply_data);
+    handle_cmd_deallocate_channel(port_id, 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);
+    handle_cmd_xmit_raw_frame(data);
     return;
   }
 
@@ -162,203 +160,195 @@
 }
 
 // Return -1 if it is not an RX port, or an index
-long usrp_server::is_tx_port(pmt_t port_id) {
+long usrp_server::tx_port_index(pmt_t port_id) {
 
   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);
+  for(int i=0; i < d_tx.size(); i++) 
+    if(pmt_eq(tx[i]->port_symbol(), port_id))
+      return i;
 
   return -1;
 }
 
 // Return -1 if it is not an RX port, or an index
-long usrp_server::is_rx_port(pmt_t port_id) {
+long usrp_server::rx_port_index(pmt_t port_id) {
   
   std::vector<mb_port_sptr>::iterator rx;
 
-  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);
+  for(int i=0; i < d_rx.size(); i++) 
+    if(pmt_eq(rx[i]->port_symbol(), port_id))
+      return i;
 
   return -1;
 }
 
-// Return one of two predicates for TX or RX ... -1 on error
-long usrp_server::get_port_type(pmt_t port_id) {
-
-  if(is_tx_port(port_id) != -1)
-    return D_PORT_TYPE_TX;
-
-  if(is_rx_port(port_id) != -1)
-    return D_PORT_TYPE_RX;
-
-  return -1;
-}
-
 // Go through all TX and RX channels, sum up the assigned capacity
 // and return it
 long usrp_server::current_capacity_allocation() {
   long capacity = 0;
 
-  for(int chan=0; chan < d_in_tx_chan; chan++) 
+  for(int chan=0; chan < d_ntx_chan; chan++) 
     capacity += d_chaninfo_tx[chan].assigned_capacity;
 
-  for(int chan=0; chan < d_in_rx_chan; chan++)
+  for(int chan=0; chan < d_nrx_chan; chan++)
     capacity += d_chaninfo_rx[chan].assigned_capacity;
 
   return capacity;
 }
     
-pmt_t usrp_server::handle_cmd_allocate_channel(pmt_t port_id, pmt_t data) {
+void usrp_server::handle_cmd_allocate_channel(pmt_t port_id, pmt_t data) {
 
   pmt_t invocation_handle = pmt_nth(0, data);
-  long assigned_capacity = pmt_to_long(pmt_nth(1, data));
-  long chan, port_type;
+  long rqstd_capacity = pmt_to_long(pmt_nth(1, data));
+  long chan, port;
+  pmt_t reply_data;
 
-  // Regardless of port type, need to ensure the capacity exists, then we
-  // will worry about finding a channel depending on type
-  if((D_USB_CAPACITY - current_capacity_allocation()) < assigned_capacity)
-    return pmt_list3(invocation_handle, PMT_F, PMT_NIL);  // no capacity 
available
-  
-  // Get the type of port sending the command which will be used to
-  // assign the capacity in the correct channel pool
-  if((port_type = get_port_type(port_id)) == -1)
-    return pmt_list3(invocation_handle, PMT_F, PMT_NIL);  // unknown port type
+  // If it's a TX port, allocate on a free channel, else check if it's a RX 
port
+  // and allocate.
+  if((port = tx_port_index(port_id)) != -1) {
 
-  if(port_type == D_PORT_TYPE_TX) {
+    // Check capacity exists
+    if((D_USB_CAPACITY - current_capacity_allocation()) < rqstd_capacity) {
+      reply_data = pmt_list3(invocation_handle, PMT_F, PMT_NIL);  // no 
capacity available
+      d_tx[port]->send(invocation_handle, reply_data);
+      return;
+    }
 
-    // Find a free channel
-    for(chan=0; chan < d_in_tx_chan; chan++) 
-      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) {
-      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));
+    // Find a free channel, assign the capacity and respond
+    for(chan=0; chan < d_ntx_chan; chan++) {
+      if(d_chaninfo_tx[chan].owner == PMT_NIL) {
+        d_chaninfo_tx[chan].owner = port_id;
+        d_chaninfo_tx[chan].assigned_capacity = rqstd_capacity;
+        reply_data = pmt_list3(invocation_handle, PMT_T, pmt_from_long(chan));
+        d_tx[port]->send(invocation_handle, reply_data);
+        return;
+      }
     }
 
-    return pmt_list3(invocation_handle, PMT_F, PMT_NIL);  // no free TX chan 
found
+    reply_data = pmt_list3(invocation_handle, PMT_F, PMT_NIL);  // no free TX 
chan found
+    d_tx[port]->send(invocation_handle, reply_data);
+    return;
   }
   
-  if(port_type == D_PORT_TYPE_RX) {
+  // Repeat the same process on the RX side if the port was not determined to 
be TX
+  if((port = rx_port_index(port_id)) != -1) {
+    
+    if((D_USB_CAPACITY - current_capacity_allocation()) < rqstd_capacity) {
+      reply_data = pmt_list3(invocation_handle, PMT_F, PMT_NIL);  // no 
capacity available
+      d_rx[port]->send(invocation_handle, reply_data);
+      return;
+    }
 
-    for(chan=0; chan < d_in_tx_chan; chan++) 
-      if(d_chaninfo_tx[chan].owner == PMT_NIL) 
-        break;
-
-    if(chan < d_in_tx_chan) {
-      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));
+    for(chan=0; chan < d_ntx_chan; chan++) {
+      if(d_chaninfo_tx[chan].owner == PMT_NIL) {
+        d_chaninfo_tx[chan].owner = port_id;
+        d_chaninfo_tx[chan].assigned_capacity = rqstd_capacity;
+        reply_data = pmt_list3(invocation_handle, PMT_T, pmt_from_long(chan));
+        d_rx[port]->send(invocation_handle, reply_data);
+        return;
+      }
     }
 
-    return pmt_list3(invocation_handle, PMT_F, PMT_NIL);  // no free RX chan 
found
+    reply_data = pmt_list3(invocation_handle, PMT_F, PMT_NIL);  // no free RX 
chan found
+    d_rx[port]->send(invocation_handle, reply_data);
+    return;
   }
 }
 
 // Check the port type and deallocate assigned capacity based on this, ensuring
 // that the owner of the method invocation is the owner of the port and that
 // the channel number is valid.
-pmt_t usrp_server::handle_cmd_deallocate_channel(pmt_t port_id, pmt_t data) {
+void usrp_server::handle_cmd_deallocate_channel(pmt_t port_id, pmt_t data) {
 
   pmt_t invocation_handle = pmt_nth(0, data); 
   long channel = pmt_to_long(pmt_nth(1, data));
-  long port_type;
+  long port;
+  pmt_t reply_data;
   
-  if((port_type = get_port_type(port_id)) == -1)
-    return pmt_list3(invocation_handle, PMT_F, PMT_NIL);  // unknown port type
-
-  if(port_type == D_PORT_TYPE_TX) {
+  // Check that the channel number is valid, and that the calling port is the 
owner
+  // of the channel, and if so remove the assigned capacity.
+  if((port = tx_port_index(port_id)) != -1) {
   
-    if(channel >= d_in_tx_chan) 
-      return pmt_list2(invocation_handle, PMT_F);   // not a legit channel 
number
+    if(channel >= d_ntx_chan) {
+      reply_data = pmt_list2(invocation_handle, PMT_F);   // not a legit 
channel number
+      d_tx[port]->send(invocation_handle, reply_data);
+      return;
+    }
 
-    if(d_chaninfo_tx[channel].owner != port_id) 
-      return pmt_list2(invocation_handle, PMT_F);   // not the owner of the 
port
+    if(d_chaninfo_tx[channel].owner != port_id) {
+      reply_data = pmt_list2(invocation_handle, PMT_F);   // not the owner of 
the port
+      d_tx[port]->send(invocation_handle, reply_data);
+      return;
+    }
 
     d_chaninfo_tx[channel].assigned_capacity = 0;
     d_chaninfo_tx[channel].owner = PMT_NIL;
 
-    return pmt_list2(invocation_handle, PMT_T);
+    reply_data = pmt_list2(invocation_handle, PMT_T);
+    d_tx[port]->send(invocation_handle, reply_data);
+    return;
   }
 
-  if(port_type == D_PORT_TYPE_RX) {
+  // Repeated process on the RX side
+  if((port = rx_port_index(port_id)) != -1) {
   
-    if(channel >= d_in_rx_chan) 
-      return pmt_list2(invocation_handle, PMT_F);   // not a legit channel 
number
+    if(channel >= d_nrx_chan) {
+      reply_data = pmt_list2(invocation_handle, PMT_F);   // not a legit 
channel number
+      d_rx[port]->send(invocation_handle, reply_data);
+      return;
+    }
 
-    if(d_chaninfo_rx[channel].owner != port_id) 
-      return pmt_list2(invocation_handle, PMT_F);   // not the owner of the 
port
+    if(d_chaninfo_rx[channel].owner != port_id) {
+      reply_data = pmt_list2(invocation_handle, PMT_F);   // not the owner of 
the port
+      d_rx[port]->send(invocation_handle, reply_data);
+      return;
+    }
 
     d_chaninfo_rx[channel].assigned_capacity = 0;
     d_chaninfo_rx[channel].owner = PMT_NIL;
 
-    return pmt_list2(invocation_handle, PMT_T);
+    reply_data = pmt_list2(invocation_handle, PMT_T);
+    d_rx[port]->send(invocation_handle, reply_data);
+    return;
   }
 
 }
 
-// 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) {
+void usrp_server::handle_cmd_xmit_raw_frame(pmt_t data) {
 
-  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;
-
+  size_t n_bytes, psize;
+  long max_payload_len = USB_PKT_SIZE-2*sizeof(uint32_t);   // we can't do 
sizeof(pkts->payload()) because it would
+                                                            // be 
sizeof(unsigned char *), other ideas?
   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);
+  const void *samples = pmt_uniform_vector_elements(pmt_nth(2, data), n_bytes);
   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);
+  long n_packets = std::ceil(n_bytes / max_payload_len);   // always at least 
1 packet
+  pmt_t v_packets = pmt_make_u8vector(USB_PKT_SIZE * n_packets, 0);
+  transport_pkt *pkts = (transport_pkt *) 
pmt_u8vector_writeable_elements(v_packets, psize);
 
-  // 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);
+  for(int n=0; n < n_packets; n++) {
 
-  // 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);
+    long payload_len = std::min((int)(n_bytes-(n*max_payload_len)), 
(int)max_payload_len);
+  
+    if(n == 0) { // first packet gets start of burst flag and timestamp
+      pkts[n].set_header(pkts[n].FL_START_OF_BURST, channel, 0, payload_len);
+      pkts[n].set_timestamp(timestamp);
+    } else {
+      pkts[n].set_header(0, channel, 0, payload_len);
+      pkts[n].set_timestamp(0xffffffff);
+    }
+
+    memcpy(pkts[n].payload(), (uint8_t *)samples+(USB_PKT_SIZE * n), 
payload_len);
+    n_bytes -= payload_len;   // decrease the number of bytes left
   }
 
-  // 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();
+  pkts[n_packets-1].set_end_of_burst();   // set the last packet's 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-13 06:24:09 UTC (rev 4978)
+++ 
gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband/usrp_server.h  
    2007-04-13 06:40:18 UTC (rev 4979)
@@ -30,18 +30,20 @@
 class usrp_server : public mb_mblock
 {
 public:
+
   // our ports
-  static const int D_PORT_TYPE_RX = 0;
-  static const int D_PORT_TYPE_TX = 1;
-  static const int D_MAX_PORTS = 4;
+  enum port_types {
+    RX_PORT = 0,
+    TX_PORT = 1
+  };
+  static const int N_PORTS = 4;
   std::vector<mb_port_sptr> d_tx, d_rx;
   mb_port_sptr d_cs;
-  
 
   static const int D_USB_CAPACITY = 32 * 1024 * 1024;
   static const int D_MAX_CHANNELS = 16;
-  long d_in_tx_chan;
-  long d_in_rx_chan;
+  long d_ntx_chan;
+  long d_nrx_chan;
 
   struct channel_info {
     long assigned_capacity;  // the capacity currently assignedby the channel
@@ -59,14 +61,12 @@
   void handle_message(mb_message_sptr msg);
 
 private:
-  pmt_t handle_cmd_allocate_channel(pmt_t port_id, pmt_t data);
-  pmt_t handle_cmd_deallocate_channel(pmt_t port_id, pmt_t data);
-  pmt_t handle_cmd_xmit_raw_frame(pmt_t data);
-  long is_rx_port(pmt_t port_id);
-  long is_tx_port(pmt_t port_id);
+  void handle_cmd_allocate_channel(pmt_t port_id, pmt_t data);
+  void handle_cmd_deallocate_channel(pmt_t port_id, pmt_t data);
+  void handle_cmd_xmit_raw_frame(pmt_t data);
+  long rx_port_index(pmt_t port_id);
+  long tx_port_index(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]