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