3 * Copyright 2007 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
7 * GNU Radio is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
12 * GNU Radio is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include <usrp_usb_interface.h>
31 #include <mb_class_registry.h>
32 #include <usrp_inband_usb_packet.h>
33 #include <fpga_regs_common.h>
35 #include <usrp_rx_stub.h>
37 #include "usrp_standard.h"
40 typedef usrp_inband_usb_packet transport_pkt;
42 #include <symbols_usrp_interface_cs.h>
43 #include <symbols_usrp_tx_cs.h>
44 #include <symbols_usrp_rx_cs.h>
45 static pmt_t s_shutdown = pmt_intern("%shutdown");
47 static const bool verbose = false;
51 // need to take number of TX and RX channels as parameter
52 usrp_usb_interface::usrp_usb_interface(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg)
53 : mb_mblock(rt, instance_name, user_arg),
59 d_rbf("inband_tx_rx.rbf")
61 // Dictionary for arguments to all of the components
62 pmt_t usrp_dict = user_arg;
64 // Default TX/RX interface
65 std::string tx_interface = "usrp_tx";
66 std::string rx_interface = "usrp_rx";
68 if (pmt_is_dict(usrp_dict)) {
70 // The 'fake-usrp' key enables the TX and RX stubs if PMT_T
71 if(pmt_t fake_usrp = pmt_dict_ref(usrp_dict,
72 pmt_intern("fake-usrp"),
74 if(pmt_eqv(fake_usrp, PMT_T)) {
75 tx_interface = "usrp_tx_stub";
76 rx_interface = "usrp_rx_stub";
81 // Read the TX interpolations
82 if(pmt_t interp_tx = pmt_dict_ref(usrp_dict,
83 pmt_intern("interp-tx"),
85 if(!pmt_eqv(interp_tx, PMT_NIL))
86 d_interp_tx = pmt_to_long(interp_tx);
89 // Read the RX interpolations
90 if(pmt_t interp_rx = pmt_dict_ref(usrp_dict,
91 pmt_intern("interp-rx"),
93 if(!pmt_eqv(interp_rx, PMT_NIL))
94 d_interp_rx = pmt_to_long(interp_rx);
98 if(pmt_t rbf = pmt_dict_ref(usrp_dict,
101 if(!pmt_eqv(rbf, PMT_NIL))
102 d_rbf = pmt_symbol_to_string(rbf);
105 // The RF center frequency
106 if(pmt_t rf_freq = pmt_dict_ref(usrp_dict,
107 pmt_intern("rf-freq"),
109 if(!pmt_eqv(rf_freq, PMT_NIL))
110 d_rf_freq = pmt_to_long(rf_freq);
115 std::cout << "[USRP_USB_INTERFACE] Setting USRP RBF to "
116 << d_rbf << std::endl;
118 std::cout << "[USRP_USB_INTERFACE] Setting TX interpolation to "
119 << d_interp_tx << std::endl;
121 std::cout << "[USRP_USB_INTERFACE] Setting RX interpolation to "
122 << d_interp_rx << std::endl;
124 std::cout << "[USRP_USB_INTERFACE] Using TX interface: "
125 << tx_interface << "\n";
127 std::cout << "[USRP_USB_INTERFACE] Using RX interface: "
128 << rx_interface << "\n";
132 d_cs = define_port("cs", "usrp-interface-cs", true, mb_port::EXTERNAL);
133 d_rx_cs = define_port("rx_cs", "usrp-rx-cs", false, mb_port::INTERNAL);
134 d_tx_cs = define_port("tx_cs", "usrp-tx-cs", false, mb_port::INTERNAL);
136 // Connect to TX and RX
137 define_component("tx", tx_interface, PMT_F);
138 define_component("rx", rx_interface, PMT_F);
139 connect("self", "rx_cs", "rx", "cs");
140 connect("self", "tx_cs", "tx", "cs");
142 // FIX ME: the code should query the FPGA to retrieve the number of channels and such
149 d_fpga_debug=true; // WARNING: DO NOT ENABLE WITH D'BOARDS OTHER THAN BASIC TX/RX
153 usrp_usb_interface::~usrp_usb_interface()
159 usrp_usb_interface::initial_transition()
165 usrp_usb_interface::handle_message(mb_message_sptr msg)
167 pmt_t event = msg->signal(); // the "name" of the message
168 pmt_t port_id = msg->port_id(); // which port it came in on
169 pmt_t data = msg->data();
170 pmt_t invocation_handle;
172 if (pmt_eq(event, s_shutdown)) // ignore (for now)
175 //------------- CONTROL / STATUS -------------//
176 if (pmt_eq(port_id, d_cs->port_symbol())) {
178 //------------ OPEN --------------//
179 if (pmt_eq(event, s_cmd_usrp_open)){
180 handle_cmd_open(data);
183 //----------- CLOSE -------------//
184 else if (pmt_eq(event, s_cmd_usrp_close)) {
185 handle_cmd_close(data);
188 //---------- NTX CHAN ----------//
189 else if (pmt_eq(event, s_cmd_usrp_ntx_chan)) {
190 invocation_handle = pmt_nth(0, data);
191 d_cs->send(s_response_usrp_ntx_chan,
192 pmt_list2(invocation_handle,
193 pmt_from_long(d_ntx_chan)));
196 //---------- NRX CHAN ----------//
197 else if (pmt_eq(event, s_cmd_usrp_nrx_chan)) {
198 invocation_handle = pmt_nth(0, data);
199 d_cs->send(s_response_usrp_nrx_chan,
200 pmt_list2(invocation_handle,
201 pmt_from_long(d_nrx_chan)));
204 //------------ WRITE -----------//
205 else if(pmt_eq(event, s_cmd_usrp_write)) {
206 handle_cmd_write(data);
209 //-------- START READING --------//
210 else if(pmt_eq(event, s_cmd_usrp_start_reading)) {
211 handle_cmd_start_reading(data);
214 //-------- STOP READING --------//
215 else if(pmt_eq(event, s_cmd_usrp_stop_reading)) {
216 handle_cmd_stop_reading(data);
223 //---------------- RX ------------------//
224 if (pmt_eq(port_id, d_rx_cs->port_symbol())) {
226 // Relay reads back up
227 if(pmt_eq(event, s_response_usrp_rx_read)) {
228 d_cs->send(s_response_usrp_read, data);
235 //---------------- TX ------------------//
236 if (pmt_eq(port_id, d_tx_cs->port_symbol())) {
238 if(pmt_eq(event, s_response_usrp_tx_write)) {
240 pmt_t invocation_handle = pmt_nth(0, data);
241 pmt_t status = pmt_nth(1, data);
242 pmt_t channel = pmt_nth(2, data);
244 d_cs->send(s_response_usrp_write,
245 pmt_list3(invocation_handle,
256 std::cout << "[USRP_USB_INTERFACE] unhandled msg: " << msg << std::endl;
260 usrp_usb_interface::handle_cmd_open(pmt_t data)
262 pmt_t invocation_handle = pmt_nth(0, data);
263 long which_usrp = pmt_to_long(pmt_nth(1, data));
267 d_cs->send(s_response_usrp_open, pmt_list2(invocation_handle, PMT_T));
272 std::cout << "[USRP_USB_INTERFACE] Handling open request for USRP " << which_usrp << "\n";
274 // Open up a standard RX and TX for communication with the USRP
276 d_utx = usrp_standard_tx::make(which_usrp,
280 4096, // USB block size
281 16, // nblocks for async transfers
287 std::cout << "[USRP_USB_INTERFACE] Failed to open TX\n";
288 reply_data = pmt_list2(invocation_handle, PMT_F);
289 d_cs->send(s_response_usrp_open, reply_data);
293 if(!d_utx->set_tx_freq (0,d_rf_freq)) { // try setting center freq to 0
295 std::cout << "[USRP_USB_INTERFACE] Failed to set center frequency on TX\n";
296 reply_data = pmt_list2(invocation_handle, PMT_F);
297 d_cs->send(s_response_usrp_open, reply_data);
304 std::cout << "[USRP_USB_INTERFACE] Setup TX channel\n";
307 usrp_standard_rx::make (which_usrp,
311 0, // set blank mode to start
312 4096, // USB block size
313 16, // number of blocks for async transfers
318 std::cout << "[usrp_server] Failed to open RX\n";
319 reply_data = pmt_list2(invocation_handle, PMT_F);
320 d_cs->send(s_response_usrp_open, reply_data);
324 if(!d_urx->set_rx_freq (0, d_rf_freq)) {
326 std::cout << "[usrp_server] Failed to set center frequency on RX\n";
327 reply_data = pmt_list2(invocation_handle, PMT_F);
328 d_cs->send(s_response_usrp_open, reply_data);
333 d_utx->_write_fpga_reg(FR_DEBUG_EN,0xf);
334 d_utx->_write_oe(0, 0xffff, 0xffff);
335 d_urx->_write_oe(0, 0xffff, 0xffff);
336 d_utx->_write_oe(1, 0xffff, 0xffff);
337 d_urx->_write_oe(1, 0xffff, 0xffff);
340 // for(int i=0; i<0xffff; i++)
341 // d_urx->write_io(0, i, 0xffff);
346 std::cout << "[USRP_USB_INTERFACE] Setup RX channel\n";
348 d_cs->send(s_response_usrp_open, pmt_list2(invocation_handle, PMT_T));
352 usrp_usb_interface::handle_cmd_write(pmt_t data)
354 pmt_t invocation_handle = pmt_nth(0, data);
355 pmt_t channel = pmt_nth(1, data);
356 pmt_t pkts = pmt_nth(2, data);
358 pmt_t tx_handle = pmt_make_any(d_utx);
360 d_tx_cs->send(s_cmd_usrp_tx_write,
361 pmt_list4(invocation_handle,
370 usrp_usb_interface::handle_cmd_start_reading(pmt_t data)
372 pmt_t invocation_handle = pmt_nth(0, data);
375 std::cout << "[USRP_USB_INTERFACE] Starting RX...\n";
380 pmt_t rx_handle = pmt_make_any(d_urx);
382 d_rx_cs->send(s_cmd_usrp_rx_start_reading, pmt_list2(PMT_NIL, rx_handle));
388 usrp_usb_interface::handle_cmd_stop_reading(pmt_t data)
390 pmt_t invocation_handle = pmt_nth(0, data);
394 std::cout << "[USRP_USB_INTERFACE] Stopping RX...\n";
399 std::cout << "[USRP_USB_INTERFACE] Stopping fake RX...\n";
400 usrp_rx_stop = true; // extern to communicate with stub to wait
407 usrp_usb_interface::handle_cmd_close(pmt_t data)
409 pmt_t invocation_handle = pmt_nth(0, data);
412 d_cs->send(s_response_usrp_close, pmt_list2(invocation_handle, PMT_T));
417 std::cout << "[USRP_USB_INTERFACE] Handling close request for USRP\n";
425 d_cs->send(s_response_usrp_close, pmt_list2(invocation_handle, PMT_T));
431 REGISTER_MBLOCK_CLASS(usrp_usb_interface);