root/ossiedev/branches/june/trunk/platform/USRP_UHD/src/USRP_UHD.cpp @ 11034

Revision 11034, 9.0 KB (checked in by june, 15 months ago)

erasing deprecated UHD function

Line 
1/****************************************************************************
2
3Copyright 2005,2006 Virginia Polytechnic Institute and State University
4
5This file is part of the OSSIE USRP_UHD Device.
6
7OSSIE USRP_UHD Device is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12OSSIE USRP_UHD Device is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with OSSIE USRP_UHD Device; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
21
22****************************************************************************/
23
24#include <byteswap.h>
25#include <iostream>
26#include <vector>
27#include <complex>
28
29#include "ossie/cf.h"
30#include "ossie/PortTypes.h"
31
32#include "ossie/ossieSupport.h"
33#include "ossie/debug.h"
34
35#include "USRP_UHD.h"
36
37USRP_UHD_i::USRP_UHD_i(char *id, char *label, char *profile) :
38        Device_impl(id, label, profile),
39        set_rx_packet_count(-1),
40        rx_packet_count(1024),
41        rx_packet_size(256),
42        rx_data_size(2),
43        number_of_channels(1),
44        complex(true),
45        rx_overruns(0),
46        rx_active(false),
47        tx_active(false),
48        full_duplex(true),
49        did_rx(false)
50{
51// Create USRP_UHD Control ports for TX and RX
52    rx_control_port = new USRP_UHD_RX_Control_i(this, "U2_RX_Control", "DomainName1");
53    tx_control_port = new USRP_UHD_TX_Control_i(this, "U2_TX_Control", "DomainName1");
54
55// Create the ports for TX data
56    tx_data_port = new standardInterfaces_i::complexShort_p("U2_TX_Data", "DomainName1");
57
58// Create the ports for RX Data
59    rx_data_1_port = new standardInterfaces_i::complexShort_u("U2_RX_Data_1", "DomainName1");
60    rx_data_2_port = new standardInterfaces_i::complexShort_u("U2_RX_Data_2", "DomainName1");
61}
62
63void USRP_UHD_i::start() throw (CF::Resource::StartError, CORBA::SystemException)
64{
65    DEBUG(3, USRP_UHD, "Start USRP_UHD called")
66}
67
68void USRP_UHD_i::stop() throw (CF::Resource::StopError, CORBA::SystemException)
69{
70    DEBUG(3, USRP_UHD, "Stop USRP_UHD called")
71    (rx_active)?std::cout<<"Active": std::cout<<"NOT Active";
72}
73
74CORBA::Object_ptr USRP_UHD_i::getPort(const char* portName)
75throw(CF::PortSupplier::UnknownPort, CORBA::SystemException)
76{
77    DEBUG(3, USRP_UHD, "USRP_UHD getPort called with : " << portName)
78
79    CORBA::Object_var p;
80
81    if (!CORBA::is_nil(p = rx_control_port->getPort(portName)))
82        return p._retn();
83    else if (!CORBA::is_nil(p = rx_data_1_port->getPort(portName)))
84        return p._retn();
85    else if (!CORBA::is_nil(p = rx_data_1_port->getPort(portName))) {
86        return p._retn();
87    } else if (!CORBA::is_nil(p = tx_control_port->getPort(portName))) {
88        return p._retn();
89    } else if (!CORBA::is_nil(p = tx_data_port->getPort(portName))) {
90        return p._retn();
91    }
92    std::cerr << "Couldn't find port " << portName << "Throwing exception" << std::endl;
93    throw CF::PortSupplier::UnknownPort();
94}
95
96void USRP_UHD_i::initialize() throw (CF::LifeCycle::InitializeError, CORBA::SystemException)
97{
98    DEBUG(3, USRP_UHD, "USRP_UHD Initialize called")
99    std::string args("");
100    DEBUG(1, USRP_UHD, "Creating the usrp device with: "<< args)
101    sdev = uhd::usrp::multi_usrp::make(args);
102    dev = sdev->get_device();
103    sdev->set_rx_antenna("RX2");
104    sdev->set_rx_antenna("TX/RX");
105    DEBUG(1, USRP_UHD, "Using Device: "<< sdev->get_pp_string())
106}
107
108void USRP_UHD_i::configure(const CF::Properties &configProperties)
109throw (CORBA::SystemException, CF::PropertySet::InvalidConfiguration,
110       CF::PropertySet::PartialConfiguration)
111{
112
113}
114
115void USRP_UHD_i::query(CF::Properties &configProperties)
116throw (CORBA::SystemException, CF::UnknownProperties)
117{
118
119}
120
121
122void USRP_UHD_i::releaseObject()
123throw (CF::LifeCycle::ReleaseError, CORBA::SystemException)
124{
125
126    DEBUG(3, USRP_UHD, "USRP_UHD releaseObject called")
127}
128
129
130void USRP_UHD_i::rx_data_process()
131{
132
133///\TODO assumes one channel operation.  Set full_deplex to false to prevent Rx buffering during Tx
134///Full duplex mode is still broken. we still cannot transmit and receive simultaneously using WBX board
135
136    //tells the device to stream samples indefinitely
137    uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
138
139    //Use with STREAM_MODE_NUM_SAMPS_AND_DONE/_MORE     
140    //stream_cmd.num_samps = 65536;
141    //stream_cmd.time_spec = uhd::time_spec_t((time_t)0);
142   
143    //When true, the device will begin streaming ASAP
144    stream_cmd.stream_now = true;
145
146    sdev->issue_stream_cmd(stream_cmd);
147
148    uhd::stream_args_t stream_args("sc16");
149    stream_args.args["noclear"] = "1";
150    uhd::rx_streamer::sptr rx_stream = sdev->get_rx_stream(stream_args);
151
152    PortTypes::ShortSequence I;
153    PortTypes::ShortSequence Q;
154   
155///\TODO Make sure rx_packet_size is >= than USRP_UHD_MIN_RX_SAMPLES!!!!!
156    rx_buff.resize(rx_packet_size);
157    I.length(rx_packet_size);
158    Q.length(rx_packet_size);
159
160    DEBUG(3, USRP_UHD, "RX packet count " << rx_packet_count)
161
162    while (rx_active && ((rx_packet_count == -1) || (rx_packet_count > 0))) {
163                uhd::rx_metadata_t md;
164        //if we are running half duplex mode we will need to tell start streaming at the beginning of the loop
165                if (full_duplex == false && did_rx == false)  {
166                        uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
167                        sdev->issue_stream_cmd(stream_cmd);
168                        did_rx = true;
169                }
170
171       
172//TODO get rid of num_rx_samps variable
173        size_t num_rx_samps = rx_stream->recv( &rx_buff.front(), rx_packet_size, md);
174       
175        //Handle UHD error codes
176        switch(md.error_code){
177            case uhd::rx_metadata_t::ERROR_CODE_NONE:
178                break;
179            case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT:
180                DEBUG(3, USRP_UHD, "Got timeout before all samples received, possible packet loss")
181                break;
182            default:
183                DEBUG(3, USRP_UHD, "Got error code 0x"<<md.error_code)
184        }
185
186                for (unsigned int i = 0; i < num_rx_samps; i++) {
187                        I[i] = (CORBA::Short) rx_buff[i].real();
188                        Q[i] = (CORBA::Short) rx_buff[i].imag();
189                }
190                rx_data_1_port->pushPacket(I, Q);
191
192                if (rx_packet_count != -1)
193                                --rx_packet_count;
194        }
195
196    DEBUG(3, USRP_UHD, "Exiting rx_data_process thread")
197    //tells the device to stop streaming samples
198    stream_cmd = uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS;
199    sdev->issue_stream_cmd(stream_cmd);
200    rx_active = false;
201    rx_thread->exit();
202}
203
204
205
206// USRP_UHD Expects data in little endian format
207static inline short convertToLE(short s)
208{
209#ifdef __powerpc__
210    s = bswap_16(s);
211#endif
212
213    return s;
214}
215
216void USRP_UHD_i::tx_data_process()
217{
218    PortTypes::ShortSequence *I_in, *Q_in;
219
220    const unsigned int tx_buf_len(USRP_UHD_MAX_TX_SAMPLES);
221
222    uhd::stream_args_t stream_args("sc16");
223    stream_args.args["noclear"] = "1";
224    uhd::tx_streamer::sptr tx_stream = sdev->get_tx_stream(stream_args);
225
226
227    uhd::tx_metadata_t md3;
228
229    //Set start and end of burst flags to help with packet fragmentation if needed
230    //Host will send ACK packets when an EOB flag is received
231    //SOB true -> first packet in sequence gets SOB flag
232    //EOB true -> last packet in sequence gets EOB flag
233    md3.start_of_burst = false; 
234    md3.end_of_burst   = false;     
235
236    //We can send packets in the future if needed
237    //md.has_time_spec  = 0;     //no time
238    //md.time_spec = uhd::time_spec_t((time_t)0 );
239
240    std::vector< std::complex<short int> > tx_buff(tx_buf_len);
241
242    DEBUG(3, USRP_UHD, "Starting tx_data_process thread.")
243   
244    tx_active = true; // Cleared to stop TX in USRP_UHD_TX_Control->stop()
245
246    while (tx_active) {
247                //if running half duplex mode we want to stop Rx streaming while transmitting
248                if (full_duplex == false && did_rx == true)  {
249                                did_rx = false;
250                        uhd::rx_metadata_t md;
251                        size_t num_rx_samps = dev->recv( &rx_buff.front(), rx_packet_size, md,
252                                                                                                uhd::io_type_t::COMPLEX_INT16,
253                                                                                                uhd::device::RECV_MODE_FULL_BUFF);
254                        sdev->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS);
255
256                }
257
258
259        tx_data_port->getData(I_in, Q_in);
260        size_t samps_to_send = I_in->length();
261       
262        if(samps_to_send > tx_buf_len){
263            std::cerr << "USRP_UHD Tx Buffer Overflow. Throwing Exception"<<std::endl;
264            throw std::runtime_error("USRP_UHD buffer overflow");
265        }
266
267        for (unsigned int i = 0; i < samps_to_send; ++i) {
268            tx_buff[i] = std::complex<short int> (convertToLE((*I_in)[i]),convertToLE((*Q_in)[i]));
269        }
270
271        //send the entire packet (driver fragments internally)
272        size_t num_tx_samps = tx_stream->send( &tx_buff.front(), samps_to_send, md3);
273        tx_data_port->bufferEmptied();
274               
275    }
276   
277    DEBUG(3, USRP_UHD, "Exiting tx_data_process thread.")
278    tx_thread->exit();
279}
Note: See TracBrowser for help on using the browser.