[Top][All Lists]
[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 */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r4965 - gnuradio/branches/developers/gnychis/inband/usrp/host/lib/inband,
gnychis <=