discuss-gnuradio
[Top][All Lists]
Advanced

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

[Discuss-gnuradio] UHD Simultaneous tx/rx Loopback Problem


From: Isaac Gerg
Subject: [Discuss-gnuradio] UHD Simultaneous tx/rx Loopback Problem
Date: Thu, 27 Jan 2011 11:08:19 -0500

Using USRP 1.

I have 3 threads running.  A rx, a tx, and a sendMessage thread.  The rx receives continuously.  I send a burst every 10 seconds with the sendMessage thread.  sendMessage posts the message to a queue (mutex locked) which triggers the tx thread to pull the message from the queue and send the samples.  Currently, I have jimmy rigged the tx thread to send one cycle of a complex exp() instead of sending the message (for debugging purposes).  However, I dont see the message on the rx side of the house. 

I look for the message by monitoring the abs() of each sample and printing out a message when the abs > 0.01.  I get about 10-20 samples that fit this criteria every 10 seconds when I should be seeing a lot more.  No matter how I vary my tx buffer length, I seem to always see the same number of samples at the rx end.

Ive gone through my code again and I dont understand why this isnt working.  Here is a dump:

Some setup code:
    m_usrpSampsPerBlock = m_pDev->get_max_recv_samps_per_packet();

    // http://ettus-apps.sourcerepo.com/redmine/ettus/projects/uhd/repository/revisions/master/entry/host/examples/benchmark_rx_rate.cpp
    // Flush rx buffer
    // idg - This seems to do nothing.
    uhd::rx_metadata_t md;
    std::vector<std::complex<float> > buff(m_usrpSampsPerBlock);
    while(m_pDev->recv(&buff.front(), buff.size(), md,uhd::io_type_t::COMPLEX_FLOAT32,uhd::device::RECV_MODE_ONE_PACKET))
    {
        // NOP
    }
    //handle the error codes
    stringstream msg;
    switch(md.error_code)
    {
        case uhd::rx_metadata_t::ERROR_CODE_NONE:
            m_pLogger->log("USRP flush OK",__FILE__,__LINE__);
            break;
        case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT:
            //if (num_acc_samps == 0) continue;
            msg << "Got timeout before all samples received, possible packet loss, exiting loop...";
            m_pLogger->log(msg.str(),__FILE__,__LINE__);
            break;
        case uhd::rx_metadata_t::ERROR_CODE_OVERFLOW:
            //if (num_acc_samps == 0) continue;
            msg << "Overflow!";
            m_pLogger->log(msg.str(),__FILE__,__LINE__);
            break;
        default:
            msg << "Got error code 0x"<< md.error_code << ", exiting loop...";
            m_pLogger->log(msg.str(),__FILE__,__LINE__);
            break;
    }

    //setup rx streaming
    m_pSdev->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);


--
The tx thread
    Int32 burstSizeSamps = 100;
    vector<complex<Float32> > vec(burstSizeSamps);

    // Set up tx params.  We wish to send a burst.
    uhd::tx_metadata_t md;
    md.start_of_burst = true;
    md.end_of_burst   = true;

    Float32 v = 0;
    for (Int32 k=0;k<vec.size();++k)
    {
        v = 2*M_PI*(Float32(k)/Float32(vec.size()));
        vec[k] = complex<Float32>(cos(v), sin(v));
        //cout << vec[k] << " ";
    }
    cout << endl;

    // Send the entire contents of the buffer
    // This should be the only place where data is sent over the air!
    cout << "sending size [cpx samps]: " << vec.size() << endl;
    m_pDev->send(&(vec.front()), vec.size(), md,uhd::io_type_t::COMPLEX_FLOAT32, uhd::device::SEND_MODE_FULL_BUFF);
}

the rx thread:
    m_pLogger->log("CTransceiver::rxThread() started.",__FILE__,__LINE__);

    uhd::set_thread_priority_safe();

    uhd::rx_metadata_t md;
    std::vector<std::complex<Float32> >* pBuff = NULL;
    stringstream msg;

    UInt64 blocksProcessed = 0;
    CTimer myTimer;
    myTimer.start();

    while (!(m_shutdown))
    {
        // Rx data
        pBuff = new vector<complex<Float32> >(m_usrpSampsPerBlock);

        size_t num_rx_samps = m_pDev->recv(&(pBuff->front()),pBuff->size(),md,uhd::io_type_t::COMPLEX_FLOAT32,uhd::device::RECV_MODE_ONE_PACKET);
        msg.str("");

        if (0 == num_rx_samps)
        {
            m_pLogger->log("No samps rx.",__FILE__,__LINE__);
        }

        //handle the error codes
        switch(md.error_code)
        {
            case uhd::rx_metadata_t::ERROR_CODE_NONE:
                break;
            case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT:
                //if (num_acc_samps == 0) continue;
                msg << "Got timeout before all samples received, possible packet loss, exiting loop...";
                m_pLogger->log(msg.str(),__FILE__,__LINE__);
                goto done_loop;
            case uhd::rx_metadata_t::ERROR_CODE_OVERFLOW:
                //if (num_acc_samps == 0) continue;
                msg << "Overflow!";
                m_pLogger->log(msg.str(),__FILE__,__LINE__);
                goto done_loop;
            default:
                msg << "Got error code 0x"<< md.error_code << ", exiting loop...";
                m_pLogger->log(msg.str(),__FILE__,__LINE__);
                goto done_loop;
        }

        done_loop:

        {
             // Lock queue
            boost::mutex::scoped_lock l(*m_pMutexRxQueue);
             // Put data block on queue
             m_pRxQueue->push_back(pBuff);
        }
    }

  // another thread wakes up and if there are blocks on the queue, it sends them to processBlock()


--
processBlock()
void CTransceiver::processBlock(vector<complex<Float32> >* pBlock)
{
    //cout << pBlock->size() << endl;
    for (Int32 k=0;k<pBlock->size();++k)
    {
        if (abs((*pBlock)[k]) > 0.01)
        {
            cout << " HERE  " << (*pBlock)[k] << " " << k << endl;
        }
    }
    delete pBlock;
}
--

My output (the logger wakes up every 1 second to write the message queue to disk)

[2011-01-27|10:57:42 -0500] (../src/Transceiver.cpp:274) USRP flush OK
[2011-01-27|10:57:42 -0500] (../src/Transceiver.cpp:296) CTransceiver::setupUsrp() setup complete.
[2011-01-27|10:57:42 -0500] (../src/Transceiver.cpp:301) CTransceiver::rxWorkerThread started.
[2011-01-27|10:57:42 -0500] (../src/Transceiver.cpp:125) CTransceiver::rxThread() started.
[2011-01-27|10:57:43 -0500] (../src/Transceiver.cpp:47) CTransceiver::txThread() started.

sending size [cpx samps]: 100
 HERE  (-0.0129704,-0.0245979) 41
 HERE  (-0.0138554,-0.0418409) 42
 HERE  (-0.0126652,-0.0428785) 43
 HERE  (-0.00927763,-0.0444044) 44
 HERE  (-0.00708029,-0.044557) 45
 HERE  (-0.00366222,-0.0450758) 46
 HERE  (-0.00152593,-0.0452284) 47
 HERE  (0.00238044,-0.0451674) 48
 HERE  (0.00332652,-0.0452284) 49
 HERE  (0.00946074,-0.0398877) 50
 HERE  (-0.004944,-0.0150456) 51
[2011-01-27|10:57:52 -0500] (../src/Transceiver.cpp:389) Posted message to Tx queue.
[2011-01-27|10:57:53 -0500] (../src/Transceiver.cpp:86) CTransceiver::txThread() sent 1 messages.

sending size [cpx samps]: 100
 HERE  (0.00979644,0.00268563) 1374
 HERE  (-0.024659,-0.0125126) 1513
 HERE  (-0.0340892,-0.027131) 1514
 HERE  (-0.0344249,-0.0291757) 1515
 HERE  (-0.0332347,-0.0318918) 1516
 HERE  (-0.0297861,-0.0314646) 1517
 HERE  (-0.0299081,-0.0389416) 1518
 HERE  (-0.0249031,-0.0137944) 1519
[2011-01-27|10:58:02 -0500] (../src/Transceiver.cpp:389) Posted message to Tx queue.
[2011-01-27|10:58:03 -0500] (../src/Transceiver.cpp:86) CTransceiver::txThread() sent 1 messages.

sending size [cpx samps]: 100
 HERE  (0.0184027,-0.00933866) 2819
 HERE  (-0.00930815,-0.0262764) 2924
 HERE  (-0.00799585,-0.0425428) 2925
 HERE  (-0.00534074,-0.0445265) 2926
 HERE  (-0.00323496,-0.0449538) 2927
 HERE  (0.000549333,-0.0451979) 2928
 HERE  (0.00173956,-0.0447401) 2929
 HERE  (0.00778222,-0.04532) 2930
 HERE  (0.000671407,-0.0408643) 2931
[2011-01-27|10:58:12 -0500] (../src/Transceiver.cpp:389) Posted message to Tx queue.
[2011-01-27|10:58:13 -0500] (../src/Transceiver.cpp:86) CTransceiver::txThread() sent 1 messages.
--

Also, the code I got from the repo to flush the rx buffer doesnt seem to work.  Upon startup, I get a bunch of samples that trip the threshold (abs()>0.01) before a message is even sent out.  Why is this?

Any help would be greatly appreciated!

Thanks,
Isaac

reply via email to

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