diff options
author | Josh Blum | 2010-05-04 13:15:57 -0700 |
---|---|---|
committer | Josh Blum | 2010-05-04 13:15:57 -0700 |
commit | b6f86944737975efde1275144c1c344e4a633146 (patch) | |
tree | 6287b1cd117425a34d9499bc69c706bd0fdc971b /usrp | |
parent | 1e4bf239c1f09a0180585de62746922bcd34b639 (diff) | |
parent | e22224454f63be561fa2a5923d35b65ba403b6ac (diff) | |
download | gnuradio-b6f86944737975efde1275144c1c344e4a633146.tar.gz gnuradio-b6f86944737975efde1275144c1c344e4a633146.tar.bz2 gnuradio-b6f86944737975efde1275144c1c344e4a633146.zip |
Merge branch 'master' of http://gnuradio.org/git/gnuradio into uhd
Diffstat (limited to 'usrp')
59 files changed, 107 insertions, 12724 deletions
diff --git a/usrp/host/lib/Makefile.am b/usrp/host/lib/Makefile.am index e80f27112..5848412c9 100644 --- a/usrp/host/lib/Makefile.am +++ b/usrp/host/lib/Makefile.am @@ -1,7 +1,7 @@ # # USRP - Universal Software Radio Peripheral # -# Copyright (C) 2003,2004,2006,2007,2008,2009 Free Software Foundation, Inc. +# Copyright (C) 2003,2004,2006,2007,2008,2009,2010 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -31,10 +31,10 @@ libusrp_la_common_LIBADD = \ $(BOOST_THREAD_LIB) \ ../misc/libmisc.la -# darwin fusb requires omnithreads +# darwin fusb requires gruel (for threading) if FUSB_TECH_darwin -AM_CPPFLAGS = $(common_INCLUDES) $(OMNITHREAD_INCLUDES) $(BOOST_CPPFLAGS) $(WITH_INCLUDES) -libusrp_la_LIBADD = $(libusrp_la_common_LIBADD) $(OMNITHREAD_LA) +AM_CPPFLAGS = $(common_INCLUDES) $(GRUEL_INCLUDES) $(BOOST_CPPFLAGS) $(WITH_INCLUDES) +libusrp_la_LIBADD = $(libusrp_la_common_LIBADD) $(GRUEL_LA) libusrp_la_LDFLAGS = $(libusrp_la_common_LDFLAGS) -framework CoreFoundation else AM_CPPFLAGS = $(common_INCLUDES) $(BOOST_CPPFLAGS) $(WITH_INCLUDES) @@ -70,7 +70,6 @@ darwin_CODE = \ circular_buffer.h \ circular_linked_list.h \ darwin_libusb.h \ - mld_threads.h \ usrp_prims_libusb0.cc diff --git a/usrp/host/lib/circular_buffer.h b/usrp/host/lib/circular_buffer.h index 6d491fb6f..48758bf87 100644 --- a/usrp/host/lib/circular_buffer.h +++ b/usrp/host/lib/circular_buffer.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006,2009 Free Software Foundation, Inc. + * Copyright 2006,2009,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio. * @@ -23,7 +23,7 @@ #ifndef _CIRCULAR_BUFFER_H_ #define _CIRCULAR_BUFFER_H_ -#include "mld_threads.h" +#include <gruel/thread.h> #include <iostream> #include <stdexcept> @@ -37,7 +37,8 @@ #define DEBUG(X) do{} while(0); #endif -template <class T> class circular_buffer +template <class T> +class circular_buffer { private: // the buffer to use @@ -48,8 +49,9 @@ private: size_t d_n_avail_write_I, d_n_avail_read_I; // stuff to control access to class internals - mld_mutex_ptr d_internal; - mld_condition_ptr d_readBlock, d_writeBlock; + gruel::mutex* d_internal; + gruel::condition_variable* d_readBlock; + gruel::condition_variable* d_writeBlock; // booleans to decide how to control reading, writing, and aborting bool d_doWriteBlock, d_doFullRead, d_doAbort; @@ -94,16 +96,14 @@ public: }; inline size_t n_avail_write_items () { - d_internal->lock (); + gruel::scoped_lock l (*d_internal); size_t retVal = d_n_avail_write_I; - d_internal->unlock (); return (retVal); }; inline size_t n_avail_read_items () { - d_internal->lock (); + gruel::scoped_lock l (*d_internal); size_t retVal = d_n_avail_read_I; - d_internal->unlock (); return (retVal); }; @@ -120,13 +120,13 @@ public: // create a mutex to handle contention of shared resources; // any routine needed access to shared resources uses lock() // before doing anything, then unlock() when finished. - d_internal = new mld_mutex (); + d_internal = new gruel::mutex (); // link the internal mutex to the read and write conditions; // when wait() is called, the internal mutex will automatically - // be unlock()'ed. Upon return (from a signal() to the condition), + // be unlock()'ed. Upon return (from a notify_one() to the condition), // the internal mutex will be lock()'ed. - d_readBlock = new mld_condition (d_internal); - d_writeBlock = new mld_condition (d_internal); + d_readBlock = new gruel::condition_variable (); + d_writeBlock = new gruel::condition_variable (); }; /* @@ -167,9 +167,8 @@ public: if (!buf) throw std::runtime_error ("circular_buffer::enqueue(): " "input buffer is NULL.\n"); - d_internal->lock (); + gruel::scoped_lock l (*d_internal); if (d_doAbort) { - d_internal->unlock (); return (2); } // set the return value to 1: success; change if needed @@ -178,11 +177,11 @@ public: if (d_doWriteBlock) { while (bufLen_I > d_n_avail_write_I) { DEBUG (std::cerr << "enqueue: #len > #a, waiting." << std::endl); - // wait will automatically unlock() the internal mutex - d_writeBlock->wait (); - // and lock() it here. + // wait; will automatically unlock() the internal mutex via + // the scoped lock + d_writeBlock->wait (l); + // and auto re-lock() it here. if (d_doAbort) { - d_internal->unlock (); DEBUG (std::cerr << "enqueue: #len > #a, aborting." << std::endl); return (2); } @@ -208,8 +207,7 @@ public: d_writeNdx_I += n_now_I; d_n_avail_read_I += bufLen_I; d_n_avail_write_I -= bufLen_I; - d_readBlock->signal (); - d_internal->unlock (); + d_readBlock->notify_one (); return (retval); }; @@ -255,19 +253,18 @@ public: throw std::runtime_error ("circular_buffer::dequeue()"); } - d_internal->lock (); + gruel::scoped_lock l (*d_internal); if (d_doAbort) { - d_internal->unlock (); return (2); } if (d_doFullRead) { while (d_n_avail_read_I < l_bufLen_I) { DEBUG (std::cerr << "dequeue: #a < #len, waiting." << std::endl); - // wait will automatically unlock() the internal mutex - d_readBlock->wait (); - // and lock() it here. + // wait; will automatically unlock() the internal mutex via + // the scoped lock + d_readBlock->wait (l); + // and re-lock() it here. if (d_doAbort) { - d_internal->unlock (); DEBUG (std::cerr << "dequeue: #a < #len, aborting." << std::endl); return (2); } @@ -276,11 +273,11 @@ public: } else { while (d_n_avail_read_I == 0) { DEBUG (std::cerr << "dequeue: #a == 0, waiting." << std::endl); - // wait will automatically unlock() the internal mutex - d_readBlock->wait (); - // and lock() it here. + // wait; will automatically unlock() the internal mutex via + // the scoped lock + d_readBlock->wait (l); + // and re-lock() it here. if (d_doAbort) { - d_internal->unlock (); DEBUG (std::cerr << "dequeue: #a == 0, aborting." << std::endl); return (2); } @@ -303,17 +300,15 @@ public: *bufLen_I = l_bufLen_I; d_n_avail_read_I -= l_bufLen_I; d_n_avail_write_I += l_bufLen_I; - d_writeBlock->signal (); - d_internal->unlock (); + d_writeBlock->notify_one (); return (1); }; void abort () { - d_internal->lock (); + gruel::scoped_lock l (*d_internal); d_doAbort = true; - d_writeBlock->signal (); - d_readBlock->signal (); - d_internal->unlock (); + d_writeBlock->notify_one (); + d_readBlock->notify_one (); }; }; diff --git a/usrp/host/lib/circular_linked_list.h b/usrp/host/lib/circular_linked_list.h index 97fe2c1a8..bbed5e49b 100644 --- a/usrp/host/lib/circular_linked_list.h +++ b/usrp/host/lib/circular_linked_list.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006,2009 Free Software Foundation, Inc. + * Copyright 2006,2009,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio. * @@ -23,7 +23,7 @@ #ifndef _CIRCULAR_LINKED_LIST_H_ #define _CIRCULAR_LINKED_LIST_H_ -#include <mld_threads.h> +#include <gruel/thread.h> #include <stdexcept> #define __INLINE__ inline @@ -110,8 +110,8 @@ template <class T> class circular_linked_list { private: s_node_ptr d_current, d_iterate, d_available, d_inUse; size_t d_n_nodes, d_n_used; - mld_mutex_ptr d_internal; - mld_condition_ptr d_ioBlock; + gruel::mutex* d_internal; + gruel::condition_variable* d_ioBlock; public: circular_linked_list (size_t n_nodes) { @@ -150,8 +150,8 @@ public: } } d_available = d_current = l_prev; - d_ioBlock = new mld_condition (); - d_internal = d_ioBlock->mutex (); + d_ioBlock = new gruel::condition_variable (); + d_internal = new gruel::mutex (); }; ~circular_linked_list () { @@ -163,19 +163,21 @@ public: } delete d_ioBlock; d_ioBlock = NULL; + delete d_internal; + d_internal = NULL; d_available = d_inUse = d_iterate = d_current = NULL; d_n_used = d_n_nodes = 0; }; s_node_ptr find_next_available_node () { - d_internal->lock (); + gruel::scoped_lock l (*d_internal); // find an available node s_node_ptr l_node = d_available; DEBUG (std::cerr << "w "); while (! l_node) { DEBUG (std::cerr << "x" << std::endl); // the ioBlock condition will automatically unlock() d_internal - d_ioBlock->wait (); + d_ioBlock->wait (l); // and lock() is here DEBUG (std::cerr << "y" << std::endl); l_node = d_available; @@ -196,13 +198,12 @@ public: l_node->insert_before (d_inUse); d_n_used++; l_node->set_not_available (); - d_internal->unlock (); return (l_node); }; void make_node_available (s_node_ptr l_node) { if (!l_node) return; - d_internal->lock (); + gruel::scoped_lock l (*d_internal); DEBUG (std::cerr << "::m_n_a: #u = " << num_used() << ", node = " << l_node << std::endl); // remove this node from the inUse list @@ -221,11 +222,8 @@ public: DEBUG (std::cerr << "s" << d_n_used); // signal the condition when new data arrives - d_ioBlock->signal (); + d_ioBlock->notify_one (); DEBUG (std::cerr << "t "); - -// unlock the mutex for thread safety - d_internal->unlock (); }; __INLINE__ void iterate_start () { d_iterate = d_current; }; @@ -233,7 +231,7 @@ public: s_node_ptr iterate_next () { #if 0 // lock the mutex for thread safety - d_internal->lock (); + gruel::scoped_lock l (*d_internal); #endif s_node_ptr l_this = NULL; if (d_iterate) { @@ -242,10 +240,6 @@ public: if (d_iterate == d_current) d_iterate = NULL; } -#if 0 -// unlock the mutex for thread safety - d_internal->unlock (); -#endif return (l_this); }; @@ -261,7 +255,7 @@ public: __INLINE__ void num_used_dec (void) { if (d_n_used != 0) --d_n_used; // signal the condition that new data has arrived - d_ioBlock->signal (); + d_ioBlock->notify_one (); }; __INLINE__ bool in_use () { return (d_n_used != 0); }; }; diff --git a/usrp/host/lib/db_wbxng.cc b/usrp/host/lib/db_wbxng.cc index b35a9cb35..bd836dfe3 100644 --- a/usrp/host/lib/db_wbxng.cc +++ b/usrp/host/lib/db_wbxng.cc @@ -80,7 +80,9 @@ wbxng_base::set_freq(double freq) actual_baseband_freq is the RF frequency that corresponds to DC in the IF. */ - freq_t int_freq = freq_t(freq); + // clamp freq + freq_t int_freq = freq_t(std::max(freq_min(), std::min(freq, freq_max()))); + bool ok = d_common->_set_freq(int_freq*2); double freq_result = (double) d_common->_get_freq()/2.0; struct freq_result_t args = {ok, freq_result}; diff --git a/usrp/host/lib/fusb_darwin.cc b/usrp/host/lib/fusb_darwin.cc index 95c4878aa..d2966c115 100644 --- a/usrp/host/lib/fusb_darwin.cc +++ b/usrp/host/lib/fusb_darwin.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006,2009 Free Software Foundation, Inc. + * Copyright 2006,2009,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio. * @@ -24,9 +24,6 @@ #include "config.h" #endif -// tell mld_threads to NOT use omni_threads, -// but rather Darwin's pthreads -#define _USE_OMNI_THREADS_ #define DO_DEBUG 0 #include <usb.h> @@ -85,10 +82,12 @@ fusb_ephandle_darwin::fusb_ephandle_darwin (fusb_devhandle_darwin* dh, l_buf = NULL; } - d_readRunning = new mld_mutex (); - d_runThreadRunning = new mld_mutex (); - d_runBlock = new mld_condition (); - d_readBlock = new mld_condition (); + d_readRunning = new gruel::mutex (); + d_runThreadRunning = new gruel::mutex (); + d_runBlock = new gruel::condition_variable (); + d_readBlock = new gruel::condition_variable (); + d_runBlock_mutex = new gruel::mutex (); + d_readBlock_mutex = new gruel::mutex (); } fusb_ephandle_darwin::~fusb_ephandle_darwin () @@ -116,6 +115,10 @@ fusb_ephandle_darwin::~fusb_ephandle_darwin () d_readRunning = NULL; delete d_runThreadRunning; d_runThreadRunning = NULL; + delete d_runBlock_mutex; + d_runBlock_mutex = NULL; + delete d_readBlock_mutex; + d_readBlock_mutex = NULL; delete d_runBlock; d_runBlock = NULL; delete d_readBlock; @@ -200,14 +203,14 @@ fusb_ephandle_darwin::start () // lock the runBlock mutex, before creating the run thread. // this guarantees that we can control execution between these 2 threads - d_runBlock->mutex ()->lock (); + gruel::scoped_lock l (*d_runBlock_mutex); // create the run thread, which allows OSX to process I/O separately - d_runThread = new mld_thread (run_thread, this); + d_runThread = new gruel::thread (run_thread, this); // wait until the run thread (and possibky read thread) are -really- // going; this will unlock the mutex before waiting for a signal () - d_runBlock->wait (); + d_runBlock->wait (l); if (usb_debug) { std::cerr << "fusb_ephandle_darwin::start: " << (d_input_p ? "read" : "write") @@ -225,12 +228,12 @@ fusb_ephandle_darwin::run_thread (void* arg) // lock the run thread running mutex; if ::stop() is called, it will // first abort() the pipe then wait for the run thread to finish, // via a lock() on this mutex - mld_mutex_ptr l_runThreadRunning = This->d_runThreadRunning; - l_runThreadRunning->lock (); + gruel::mutex* l_runThreadRunning = This->d_runThreadRunning; + gruel::scoped_lock l0 (*l_runThreadRunning); - mld_mutex_ptr l_readRunning = This->d_readRunning; - mld_condition_ptr l_readBlock = This->d_readBlock; - mld_mutex_ptr l_readBlock_mutex = l_readBlock->mutex (); + gruel::mutex* l_readRunning = This->d_readRunning; + gruel::condition_variable* l_readBlock = This->d_readBlock; + gruel::mutex* l_readBlock_mutex = This->d_readBlock_mutex; bool l_input_p = This->d_input_p; @@ -250,41 +253,39 @@ fusb_ephandle_darwin::run_thread (void* arg) // get run loop reference, to allow other threads to stop This->d_CFRunLoopRef = CFRunLoopGetCurrent (); - mld_thread_ptr l_rwThread = NULL; + gruel::thread* l_rwThread = NULL; if (l_input_p) { // lock the readBlock mutex, before creating the read thread. // this guarantees that we can control execution between these 2 threads - l_readBlock_mutex->lock (); + gruel::scoped_lock l1 (*l_readBlock_mutex); // create the read thread, which just issues all of the starting // async read commands, then returns - l_rwThread = new mld_thread (read_thread, arg); + l_rwThread = new gruel::thread (read_thread, arg); // wait until the the read thread is -really- going; this will // unlock the read block mutex before waiting for a signal () - l_readBlock->wait (); + l_readBlock->wait (l1); } - // now signal the run condition to release and finish ::start(). + { + // now signal the run condition to release and finish ::start(). - // lock the runBlock mutex first; this will force waiting until the - // ->wait() command is issued in ::start() - mld_mutex_ptr l_run_block_mutex = This->d_runBlock->mutex (); - l_run_block_mutex->lock (); + // lock the runBlock mutex first; this will force waiting until the + // ->wait() command is issued in ::start() + gruel::mutex* l_run_block_mutex = This->d_runBlock_mutex; + gruel::scoped_lock l2 (*l_run_block_mutex); - // now that the lock is in place, signal the parent thread that - // things are running - This->d_runBlock->signal (); - - // release the run_block mutex, just in case - l_run_block_mutex->unlock (); + // now that the lock is in place, signal the parent thread that + // things are running + This->d_runBlock->notify_one (); + } // run the loop CFRunLoopRun (); if (l_input_p) { // wait for read_thread () to finish, if needed - l_readRunning->lock (); - l_readRunning->unlock (); + gruel::scoped_lock l3 (*l_readRunning); } // remove run loop stuff @@ -295,9 +296,6 @@ fusb_ephandle_darwin::run_thread (void* arg) std::cerr << "fusb_ephandle_darwin::run_thread: finished for " << (l_input_p ? "read" : "write") << "." << std::endl; } - - // release the run thread running mutex - l_runThreadRunning->unlock (); } void @@ -311,23 +309,23 @@ fusb_ephandle_darwin::read_thread (void* arg) // before doing anything else, lock the read running mutex. this // mutex does flow control between this thread and the run_thread - mld_mutex_ptr l_readRunning = This->d_readRunning; - l_readRunning->lock (); + gruel::mutex* l_readRunning = This->d_readRunning; + gruel::scoped_lock l0 (*l_readRunning); // signal the read condition from run_thread() to continue // lock the readBlock mutex first; this will force waiting until the // ->wait() command is issued in ::run_thread() - mld_condition_ptr l_readBlock = This->d_readBlock; - mld_mutex_ptr l_read_block_mutex = l_readBlock->mutex (); - l_read_block_mutex->lock (); + gruel::condition_variable* l_readBlock = This->d_readBlock; + gruel::mutex* l_read_block_mutex = This->d_readBlock_mutex; - // now that the lock is in place, signal the parent thread that - // things are running here - l_readBlock->signal (); + { + gruel::scoped_lock l1 (*l_read_block_mutex); - // release the run_block mutex, just in case - l_read_block_mutex->unlock (); + // now that the lock is in place, signal the parent thread that + // things are running here + l_readBlock->notify_one (); + } // queue up all of the available read requests s_queue_ptr l_queue = This->d_queue; @@ -341,10 +339,6 @@ fusb_ephandle_darwin::read_thread (void* arg) if (usb_debug) { std::cerr << "fusb_ephandle_darwin::read_thread: finished." << std::endl; } - - // release the read running mutex, to let the parent thread knows - // that this thread is finished - l_readRunning->unlock (); } void @@ -569,8 +563,7 @@ fusb_ephandle_darwin::stop () CFRunLoopStop (d_CFRunLoopRef); // wait for the runThread to stop - d_runThreadRunning->lock (); - d_runThreadRunning->unlock (); + gruel::scoped_lock l (*d_runThreadRunning); if (usb_debug) { std::cerr << "fusb_ephandle_darwin::stop: " << (d_input_p ? "read" : "write") diff --git a/usrp/host/lib/fusb_darwin.h b/usrp/host/lib/fusb_darwin.h index 735e5f16d..4d18177be 100644 --- a/usrp/host/lib/fusb_darwin.h +++ b/usrp/host/lib/fusb_darwin.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006,2009 Free Software Foundation, Inc. + * Copyright 2006,2009,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio. * @@ -150,8 +150,8 @@ class fusb_ephandle_darwin : public fusb_ephandle { private: fusb_devhandle_darwin* d_devhandle; - mld_thread_ptr d_runThread; - mld_mutex_ptr d_runThreadRunning; + gruel::thread* d_runThread; + gruel::mutex* d_runThreadRunning; CFRunLoopRef d_CFRunLoopRef; @@ -174,8 +174,11 @@ public: s_queue_ptr d_queue; circular_buffer<char>* d_buffer; size_t d_bufLenBytes; - mld_mutex_ptr d_readRunning; - mld_condition_ptr d_runBlock, d_readBlock; + gruel::mutex* d_readRunning; + gruel::mutex* d_runBlock_mutex; + gruel::mutex* d_readBlock_mutex; + gruel::condition_variable* d_runBlock; + gruel::condition_variable* d_readBlock; // CREATORS diff --git a/usrp/host/lib/mld_threads.h b/usrp/host/lib/mld_threads.h deleted file mode 100644 index 322f557b6..000000000 --- a/usrp/host/lib/mld_threads.h +++ /dev/null @@ -1,275 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2006 Free Software Foundation, Inc. - * - * This file is part of GNU Radio. - * - * Primary Author: Michael Dickens, NCIP Lab, University of Notre Dame - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef _INCLUDED_MLD_THREADS_H_ -#define _INCLUDED_MLD_THREADS_H_ - -/* classes which allow for either pthreads or omni_threads */ - -#define __macos__ -#ifdef _USE_OMNI_THREADS_ -#include <gnuradio/omnithread.h> -#else -#include <pthread.h> -#endif - -#include <stdexcept> - -#define __INLINE__ inline - -#ifndef DO_DEBUG -#define DO_DEBUG 0 -#endif - -#if DO_DEBUG -#define DEBUG(X) do{X} while(0); -#else -#define DEBUG(X) do{} while(0); -#endif - -class mld_condition_t; - -class mld_mutex_t { -#ifdef _USE_OMNI_THREADS_ - typedef omni_mutex l_mutex, *l_mutex_ptr; -#else - typedef pthread_mutex_t l_mutex, *l_mutex_ptr; -#endif - - friend class mld_condition_t; - -private: - l_mutex_ptr d_mutex; - -protected: - inline l_mutex_ptr mutex () { return (d_mutex); }; - -public: - __INLINE__ mld_mutex_t () { -#ifdef _USE_OMNI_THREADS_ - d_mutex = new omni_mutex (); -#else - d_mutex = (l_mutex_ptr) new l_mutex; - int l_ret = pthread_mutex_init (d_mutex, NULL); - if (l_ret != 0) { - fprintf (stderr, "Error %d creating mutex.\n", l_ret); - throw std::runtime_error ("mld_mutex_t::mld_mutex_t()\n"); - } -#endif - }; - - __INLINE__ ~mld_mutex_t () { - unlock (); -#ifndef _USE_OMNI_THREADS_ - int l_ret = pthread_mutex_destroy (d_mutex); - if (l_ret != 0) { - fprintf (stderr, "mld_mutex_t::~mld_mutex_t(): " - "Error %d destroying mutex.\n", l_ret); - } -#endif - delete d_mutex; - d_mutex = NULL; - }; - - __INLINE__ void lock () { -#ifdef _USE_OMNI_THREADS_ - d_mutex->lock (); -#else - int l_ret = pthread_mutex_lock (d_mutex); - if (l_ret != 0) { - fprintf (stderr, "mld_mutex_t::lock(): " - "Error %d locking mutex.\n", l_ret); - } -#endif - }; - - __INLINE__ void unlock () { -#ifdef _USE_OMNI_THREADS_ - d_mutex->unlock (); -#else - int l_ret = pthread_mutex_unlock (d_mutex); - if (l_ret != 0) { - fprintf (stderr, "mld_mutex_t::unlock(): " - "Error %d locking mutex.\n", l_ret); - } -#endif - }; - - __INLINE__ bool trylock () { -#ifdef _USE_OMNI_THREADS_ - int l_ret = d_mutex->trylock (); -#else - int l_ret = pthread_mutex_unlock (d_mutex); -#endif - return (l_ret == 0 ? true : false); - }; - - inline void acquire () { lock(); }; - inline void release () { unlock(); }; - inline void wait () { lock(); }; - inline void post () { unlock(); }; -}; - -typedef mld_mutex_t mld_mutex, *mld_mutex_ptr; - -class mld_condition_t { -#ifdef _USE_OMNI_THREADS_ - typedef omni_condition l_condition, *l_condition_ptr; -#else - typedef pthread_cond_t l_condition, *l_condition_ptr; -#endif - -private: - l_condition_ptr d_condition; - mld_mutex_ptr d_mutex; - bool d_i_own_mutex; - -public: - __INLINE__ mld_condition_t (mld_mutex_ptr mutex = NULL) { - if (mutex) { - d_i_own_mutex = false; - d_mutex = mutex; - } else { - d_i_own_mutex = true; - d_mutex = new mld_mutex (); - } -#ifdef _USE_OMNI_THREADS_ - d_condition = new omni_condition (d_mutex->mutex ()); -#else - d_condition = (l_condition_ptr) new l_condition; - int l_ret = pthread_cond_init (d_condition, NULL); - if (l_ret != 0) { - fprintf (stderr, "Error %d creating condition.\n", l_ret); - throw std::runtime_error ("mld_condition_t::mld_condition_t()\n"); - } -#endif - }; - - __INLINE__ ~mld_condition_t () { - signal (); -#ifndef _USE_OMNI_THREADS_ - int l_ret = pthread_cond_destroy (d_condition); - if (l_ret != 0) { - fprintf (stderr, "mld_condition_t::mld_condition_t(): " - "Error %d destroying condition.\n", l_ret); - } -#endif - delete d_condition; - d_condition = NULL; - if (d_i_own_mutex) - delete d_mutex; - d_mutex = NULL; - }; - - __INLINE__ mld_mutex_ptr mutex () {return (d_mutex);}; - - __INLINE__ void signal () { - DEBUG (fprintf (stderr, "a ");); - -#ifdef _USE_OMNI_THREADS_ - d_condition->signal (); -#else - int l_ret = pthread_cond_signal (d_condition); - if (l_ret != 0) { - fprintf (stderr, "mld_condition_t::signal(): " - "Error %d.\n", l_ret); - } -#endif - DEBUG (fprintf (stderr, "b ");); - }; - - __INLINE__ void wait () { - DEBUG (fprintf (stderr, "c ");); -#ifdef _USE_OMNI_THREADS_ - d_condition->wait (); -#else - int l_ret = pthread_cond_wait (d_condition, d_mutex->mutex ()); - if (l_ret != 0) { - fprintf (stderr, "mld_condition_t::wait(): " - "Error %d.\n", l_ret); - } -#endif - DEBUG (fprintf (stderr, "d ");); - }; -}; - -typedef mld_condition_t mld_condition, *mld_condition_ptr; - -class mld_thread_t { -#ifdef _USE_OMNI_THREADS_ - typedef omni_thread l_thread, *l_thread_ptr; -#else - typedef pthread_t l_thread, *l_thread_ptr; -#endif - -private: -#ifndef _USE_OMNI_THREADS_ - l_thread d_thread; - void (*d_start_routine)(void*); - void *d_arg; -#else - l_thread_ptr d_thread; -#endif - -#ifndef _USE_OMNI_THREADS_ - static void* local_start_routine (void *arg) { - mld_thread_t* This = (mld_thread_t*) arg; - (*(This->d_start_routine))(This->d_arg); - return (NULL); - }; -#endif - -public: - __INLINE__ mld_thread_t (void (*start_routine)(void *), void *arg) { -#ifdef _USE_OMNI_THREADS_ - d_thread = new omni_thread (start_routine, arg); - d_thread->start (); -#else - d_start_routine = start_routine; - d_arg = arg; - int l_ret = pthread_create (&d_thread, NULL, local_start_routine, this); - if (l_ret != 0) { - fprintf (stderr, "Error %d creating thread.\n", l_ret); - throw std::runtime_error ("mld_thread_t::mld_thread_t()\n"); - } -#endif - }; - - __INLINE__ ~mld_thread_t () { -#ifdef _USE_OMNI_THREADS_ -// delete d_thread; - d_thread = NULL; -#else - int l_ret = pthread_detach (d_thread); - if (l_ret != 0) { - fprintf (stderr, "Error %d detaching thread.\n", l_ret); - throw std::runtime_error ("mld_thread_t::~mld_thread_t()\n"); - } -#endif - }; -}; - -typedef mld_thread_t mld_thread, *mld_thread_ptr; - -#endif /* _INCLUDED_MLD_THREADS_H_ */ diff --git a/usrp/limbo/apps-inband/.gitignore b/usrp/limbo/apps-inband/.gitignore deleted file mode 100644 index f62d9e1de..000000000 --- a/usrp/limbo/apps-inband/.gitignore +++ /dev/null @@ -1,35 +0,0 @@ -/Makefile -/Makefile.in -/.la -/.lo -/.deps -/.libs -/*.la -/*.lo -/*.dat -/.*.swp -/usrper -/usrper2 -/test_input -/test_fusb -/test_usrp -/test_usrp0 -/test_usrp_standard_rx -/test_usrp_standard_tx -/test_usrp_standard_2tx -/test_usrp_inband_timestamps -/test_usrp_inband_registers -/test_usrp_inband_rx -/test_usrp_inband_2rx -/test_usrp_inband_tx -/test_usrp_inband_2tx -/test_usrp_basic_rx -/check_order_quickly -/usrp_cal_dc_offset -/test_usrp_inband_cs -/read_packets -/test_usrp_inband_ping -/test_usrp_inband_underrun -/test_usrp_inband_overrun -/gmac_mbh.cc -/test_gmac_tx diff --git a/usrp/limbo/apps-inband/Makefile.am b/usrp/limbo/apps-inband/Makefile.am deleted file mode 100644 index 0a44d8112..000000000 --- a/usrp/limbo/apps-inband/Makefile.am +++ /dev/null @@ -1,77 +0,0 @@ -# -# Copyright 2003,2006,2008 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -include $(top_srcdir)/Makefile.common - -AM_CPPFLAGS = \ - $(DEFINES) $(OMNITHREAD_INCLUDES) $(PMT_INCLUDES) $(MBLOCK_INCLUDES) \ - $(USRP_INCLUDES) $(USRP_INBAND_INCLUDES) $(BOOST_CPPFLAGS) \ - $(CPPUNIT_INCLUDES) $(WITH_INCLUDES) -I$(top_srcdir)/mblock/src/lib - - -bin_PROGRAMS = - -noinst_PROGRAMS = \ - test_usrp_inband_ping \ - test_usrp_inband_registers \ - test_usrp_inband_rx \ - test_usrp_inband_2rx \ - test_usrp_inband_tx \ - test_usrp_inband_2tx \ - test_usrp_inband_timestamps \ - test_usrp_inband_overrun \ - test_usrp_inband_underrun \ - read_packets - -noinst_HEADERS = \ - ui_nco.h \ - ui_sincos.h - - -test_usrp_inband_ping_SOURCES = test_usrp_inband_ping.cc -test_usrp_inband_ping_LDADD = $(USRP_LA) $(USRP_INBAND_LA) - -test_usrp_inband_tx_SOURCES = test_usrp_inband_tx.cc ui_sincos.c -test_usrp_inband_tx_LDADD = $(USRP_LA) $(USRP_INBAND_LA) - -test_usrp_inband_2tx_SOURCES = test_usrp_inband_2tx.cc ui_sincos.c -test_usrp_inband_2tx_LDADD = $(USRP_LA) $(USRP_INBAND_LA) - -test_usrp_inband_timestamps_SOURCES = test_usrp_inband_timestamps.cc ui_sincos.c -test_usrp_inband_timestamps_LDADD = $(USRP_LA) $(USRP_INBAND_LA) - -test_usrp_inband_registers_SOURCES = test_usrp_inband_registers.cc ui_sincos.c -test_usrp_inband_registers_LDADD = $(USRP_LA) $(USRP_INBAND_LA) - -test_usrp_inband_overrun_SOURCES = test_usrp_inband_overrun.cc -test_usrp_inband_overrun_LDADD = $(USRP_LA) $(USRP_INBAND_LA) - -test_usrp_inband_underrun_SOURCES = test_usrp_inband_underrun.cc -test_usrp_inband_underrun_LDADD = $(USRP_LA) $(USRP_INBAND_LA) - -test_usrp_inband_rx_SOURCES = test_usrp_inband_rx.cc ui_sincos.c -test_usrp_inband_rx_LDADD = $(USRP_LA) $(USRP_INBAND_LA) - -test_usrp_inband_2rx_SOURCES = test_usrp_inband_2rx.cc ui_sincos.c -test_usrp_inband_2rx_LDADD = $(USRP_LA) $(USRP_INBAND_LA) - -read_packets_SOURCES = read_packets.cc -read_packets_LDADD = $(USRP_LA) $(USRP_INBAND_LA) diff --git a/usrp/limbo/apps-inband/read_packets.cc b/usrp/limbo/apps-inband/read_packets.cc deleted file mode 100644 index 24a1e88b5..000000000 --- a/usrp/limbo/apps-inband/read_packets.cc +++ /dev/null @@ -1,109 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <iostream> -#include <usrp_inband_usb_packet.h> -#include <mblock/class_registry.h> -#include <vector> -#include <usrp_usb_interface.h> -#include <fstream> - -typedef usrp_inband_usb_packet transport_pkt; // makes conversion to gigabit easy - -int main(int argc, char *argv[]) { - - if(argc !=2) { - std::cout << "Usage: ./read_packets <data_file>\n"; - return -1; - } - - std::ifstream infile; - std::ofstream outfile; - - unsigned int pkt_size = transport_pkt::max_pkt_size(); - unsigned int pkt_num=0; - - transport_pkt *pkt; - char pkt_data[pkt_size]; // allocate the number of bytes for a single packet - - pkt = (transport_pkt *)pkt_data; // makes operations cleaner to read - - // Open the file and read the packets, dumping information - infile.open(argv[1], std::ios::binary|std::ios::in); - if(!infile.is_open()) - exit(-1); - - //outfile.open("dump.dat",std::ios::out|std::ios::binary); - - // read 1 packet in to the memory - infile.read(pkt_data, pkt_size); - - while(!infile.eof()) { - - printf("Packet %u\n", pkt_num); - - if(pkt->start_of_burst()) - printf("\tstart of burst\n"); - - if(pkt->end_of_burst()) - printf("\tend of burst\n"); - -// if(pkt->carrier_sense()) -// printf("\tcarrier sense\n"); - - if(pkt->underrun()) - printf("\tunderrun\n"); - - if(pkt->overrun()) - printf("\toverrun\n"); - - printf("\tchannel: \t0x%x\n", pkt->chan()); - printf("\ttimestamp: \t0x%x\n", pkt->timestamp()); - //printf("\ttimestamp: \t%u\n", pkt->timestamp()); - printf("\tlength: \t%u\n", pkt->payload_len()); - printf("\trssi: \t%u\n", pkt->rssi()); - - printf("\tpayload: \n"); - for(int i=0; i < pkt->payload_len(); i++) - //for(int i=0; i < pkt->max_payload(); i++) - { - printf("\t%d\t0x%x\n", i, *(pkt->payload()+i)); - //outfile.write((const char*)(pkt->payload()+i),1); - //printf("\t\t0x%x\n", pkt->payload()+i); - - } - printf("\n\n"); - - pkt_num++; - - // read 1 packet in to the memory - infile.read(pkt_data, pkt_size); - - } - - infile.close(); - //outfile.close(); - -} diff --git a/usrp/limbo/apps-inband/test_usrp_inband_2rx.cc b/usrp/limbo/apps-inband/test_usrp_inband_2rx.cc deleted file mode 100644 index c210f196a..000000000 --- a/usrp/limbo/apps-inband/test_usrp_inband_2rx.cc +++ /dev/null @@ -1,371 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <mblock/mblock.h> -#include <mblock/runtime.h> -#include <mb_runtime_nop.h> // QA only -#include <mblock/protocol_class.h> -#include <mblock/exception.h> -#include <mblock/msg_queue.h> -#include <mblock/message.h> -#include <mb_mblock_impl.h> -#include <mblock/msg_accepter.h> -#include <mblock/class_registry.h> -#include <pmt.h> -#include <stdio.h> -#include <string.h> -#include <iostream> -#include <fstream> - -// Include the symbols needed for communication with USRP server -#include <symbols_usrp_server_cs.h> -#include <symbols_usrp_channel.h> -#include <symbols_usrp_low_level_cs.h> -#include <symbols_usrp_rx.h> - -static bool verbose = true; - -class test_usrp_rx : public mb_mblock -{ - mb_port_sptr d_rx; - mb_port_sptr d_cs; - pmt_t d_rx_chan0, d_rx_chan1; - - enum state_t { - INIT, - OPENING_USRP, - ALLOCATING_CHANNEL, - RECEIVING, - CLOSING_CHANNEL, - CLOSING_USRP, - }; - - state_t d_state; - - std::ofstream d_ofile; - - long d_samples_recvd; - long d_samples_to_recv; - - public: - test_usrp_rx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg); - ~test_usrp_rx(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - protected: - void open_usrp(); - void close_usrp(); - void allocate_channel(); - void send_packets(); - void enter_receiving(); - void build_and_send_next_frame(); - void handle_response_recv_raw_samples(pmt_t invocation_handle); - void enter_closing_channel(); -}; - -test_usrp_rx::test_usrp_rx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(runtime, instance_name, user_arg), - d_rx_chan0(PMT_NIL), d_rx_chan1(PMT_NIL), - d_samples_recvd(0), - d_samples_to_recv(20e6) -{ - d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL); - d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL); - - // Pass a dictionary to usrp_server which specifies which interface to use, the stub or USRP - pmt_t usrp_dict = pmt_make_dict(); - - // To test the application without a USRP - bool fake_usrp_p = false; - if(fake_usrp_p) { - pmt_dict_set(usrp_dict, - pmt_intern("fake-usrp"), - PMT_T); - } - - // Specify the RBF to use - pmt_dict_set(usrp_dict, - pmt_intern("rbf"), - pmt_intern("inband_2rxhb_2tx.rbf")); - - pmt_dict_set(usrp_dict, - pmt_intern("decim-rx"), - pmt_from_long(64)); - - define_component("server", "usrp_server", usrp_dict); - - connect("self", "rx0", "server", "rx0"); - connect("self", "cs", "server", "cs"); - -} - -test_usrp_rx::~test_usrp_rx() -{ -} - -void -test_usrp_rx::initial_transition() -{ - open_usrp(); -} - -void -test_usrp_rx::handle_message(mb_message_sptr msg) -{ - pmt_t event = msg->signal(); - pmt_t data = msg->data(); - - pmt_t handle = PMT_F; - pmt_t status = PMT_F; - std::string error_msg; - - switch(d_state){ - - //----------------------------- OPENING_USRP ----------------------------// - // We only expect a response from opening the USRP which should be succesful - // or failed. - case OPENING_USRP: - if (pmt_eq(event, s_response_open)){ - status = pmt_nth(1, data); - if (pmt_eq(status, PMT_T)){ - allocate_channel(); - return; - } - else { - error_msg = "failed to open usrp:"; - goto bail; - } - } - goto unhandled; - - //----------------------- ALLOCATING CHANNELS --------------------// - // Allocate an RX channel to perform the overrun test. - case ALLOCATING_CHANNEL: - if (pmt_eq(event, s_response_allocate_channel)){ - status = pmt_nth(1, data); - if(pmt_eqv(d_rx_chan0, PMT_NIL)) - d_rx_chan0 = pmt_nth(2, data); - else - d_rx_chan1 = pmt_nth(2, data); - - if (pmt_eq(status, PMT_T) && !pmt_eqv(d_rx_chan1, PMT_NIL)){ - enter_receiving(); - return; - } - else if(pmt_eq(status, PMT_F)){ - error_msg = "failed to allocate channel:"; - goto bail; - } - return; - } - goto unhandled; - - //--------------------------- RECEIVING ------------------------------// - // In the receiving state, we receive samples until the specified amount - // while counting the number of overruns. - case RECEIVING: - if (pmt_eq(event, s_response_recv_raw_samples)){ - status = pmt_nth(1, data); - - if (pmt_eq(status, PMT_T)){ - handle_response_recv_raw_samples(data); - return; - } - else { - error_msg = "bad response-xmit-raw-frame:"; - goto bail; - } - } - goto unhandled; - - //------------------------- CLOSING CHANNEL ----------------------------// - // Check deallocation response for the RX channel - case CLOSING_CHANNEL: - if (pmt_eq(event, s_response_deallocate_channel)){ - status = pmt_nth(1, data); - - if (pmt_eq(status, PMT_T)){ - close_usrp(); - return; - } - else { - error_msg = "failed to deallocate channel:"; - goto bail; - } - } - - // Alternately, we ignore all response recv samples while waiting for the - // channel to actually close - if (pmt_eq(event, s_response_recv_raw_samples)) - return; - - 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)){ - fflush(stdout); - shutdown_all(PMT_T); - return; - } - else { - error_msg = "failed to close USRP:"; - goto bail; - } - } - goto unhandled; - - default: - goto unhandled; - } - return; - - // An error occured, print it, and shutdown all m-blocks - bail: - std::cerr << error_msg << data - << "status = " << status << std::endl; - shutdown_all(PMT_F); - return; - - // Received an unhandled message for a specific state - unhandled: - if(verbose && !pmt_eq(event, pmt_intern("%shutdown"))) - std::cout << "test_usrp_inband_tx: unhandled msg: " << msg - << "in state "<< d_state << std::endl; -} - - -void -test_usrp_rx::open_usrp() -{ - pmt_t which_usrp = pmt_from_long(0); - - d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, which_usrp)); - d_state = OPENING_USRP; - - if(verbose) - std::cout << "[TEST_USRP_INBAND_RX] Opening the USRP\n"; -} - -void -test_usrp_rx::close_usrp() -{ - - d_cs->send(s_cmd_close, pmt_list1(PMT_NIL)); - d_state = CLOSING_USRP; - - if(verbose) - std::cout << "[TEST_USRP_INBAND_RX] Closing the USRP\n"; -} - -void -test_usrp_rx::allocate_channel() -{ - long capacity = (long) 16e6; - d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity))); - d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity))); - d_state = ALLOCATING_CHANNEL; - - if(verbose) - std::cout << "[TEST_USRP_INBAND_RX] Requesting RX channel allocation\n"; -} - -void -test_usrp_rx::enter_receiving() -{ - d_state = RECEIVING; - - d_rx->send(s_cmd_start_recv_raw_samples, - pmt_list2(PMT_F, - d_rx_chan0)); - - d_rx->send(s_cmd_start_recv_raw_samples, - pmt_list2(PMT_F, - d_rx_chan1)); - - if(verbose) - std::cout << "[TEST_USRP_INBAND_RX] Receiving...\n"; -} - -void -test_usrp_rx::handle_response_recv_raw_samples(pmt_t data) -{ - pmt_t invocation_handle = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - pmt_t v_samples = pmt_nth(2, data); - pmt_t timestamp = pmt_nth(3, data); - pmt_t channel = pmt_nth(4, data); - pmt_t properties = pmt_nth(5, data); - - d_samples_recvd += pmt_length(v_samples) / 4; - - // Check for overrun - if(!pmt_is_dict(properties)) { - std::cout << "[TEST_USRP_INBAND_RX] Recv samples dictionary is improper\n"; - return; - } - - // Check if the number samples we have received meets the test - if(d_samples_recvd >= d_samples_to_recv) { - d_rx->send(s_cmd_stop_recv_raw_samples, pmt_list2(PMT_NIL, d_rx_chan0)); - d_rx->send(s_cmd_stop_recv_raw_samples, pmt_list2(PMT_NIL, d_rx_chan1)); - enter_closing_channel(); - return; - } - -} - -void -test_usrp_rx::enter_closing_channel() -{ - d_state = CLOSING_CHANNEL; - - d_rx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_rx_chan0)); - d_rx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_rx_chan1)); - - if(verbose) - std::cout << "[TEST_USRP_INBAND_RX] Deallocating RX channel\n"; -} - -REGISTER_MBLOCK_CLASS(test_usrp_rx); - - -// ---------------------------------------------------------------- - -int -main (int argc, char **argv) -{ - mb_runtime_sptr rt = mb_make_runtime(); - pmt_t result = PMT_NIL; - - rt->run("top", "test_usrp_rx", PMT_F, &result); - -} diff --git a/usrp/limbo/apps-inband/test_usrp_inband_2tx.cc b/usrp/limbo/apps-inband/test_usrp_inband_2tx.cc deleted file mode 100644 index 11a1a491c..000000000 --- a/usrp/limbo/apps-inband/test_usrp_inband_2tx.cc +++ /dev/null @@ -1,430 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <mblock/mblock.h> -#include <mblock/runtime.h> -#include <mb_runtime_nop.h> // QA only -#include <mblock/protocol_class.h> -#include <mblock/exception.h> -#include <mblock/msg_queue.h> -#include <mblock/message.h> -#include <mb_mblock_impl.h> -#include <mblock/msg_accepter.h> -#include <mblock/class_registry.h> -#include <pmt.h> -#include <stdio.h> -#include <string.h> -#include <iostream> - -#include <ui_nco.h> -#include <symbols_usrp_server_cs.h> -#include <symbols_usrp_channel.h> -#include <symbols_usrp_low_level_cs.h> -#include <symbols_usrp_tx.h> - -static bool verbose = true; - -class test_usrp_tx : public mb_mblock -{ - mb_port_sptr d_tx; - mb_port_sptr d_cs; - pmt_t d_tx_chan0, d_tx_chan1; - - enum state_t { - INIT, - OPENING_USRP, - ALLOCATING_CHANNEL, - TRANSMITTING, - CLOSING_CHANNEL, - 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; - - public: - test_usrp_tx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg); - ~test_usrp_tx(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - protected: - void open_usrp(); - void close_usrp(); - void allocate_channel(); - void send_packets(); - void enter_transmitting(); - void build_and_send_next_frame(); - void handle_xmit_response(pmt_t invocation_handle); - void enter_closing_channel(); -}; - -test_usrp_tx::test_usrp_tx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(runtime, instance_name, user_arg), - d_tx_chan0(PMT_NIL), d_tx_chan1(PMT_NIL), - d_state(INIT), d_nsamples_to_send((long) 80e6), - d_nsamples_xmitted(0), - d_nframes_xmitted(0), - d_samples_per_frame((long)(126 * 4)), // full packet - d_done_sending(false), - d_amplitude(16384) -{ - // std::cout << "[TEST_USRP_TX] Initializing...\n"; - - d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL); - d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL); - - //bool fake_usrp_p = true; - bool fake_usrp_p = false; - - // Test the TX side - - pmt_t usrp_dict = pmt_make_dict(); - - if(fake_usrp_p) { - pmt_dict_set(usrp_dict, - pmt_intern("fake-usrp"), - PMT_T); - } - - // Specify the RBF to use - pmt_dict_set(usrp_dict, - pmt_intern("rbf"), - pmt_intern("inband_2rxhb_2tx.rbf")); - - // Set TX and RX interpolations - pmt_dict_set(usrp_dict, - pmt_intern("interp-tx"), - pmt_from_long(128)); - -// pmt_dict_set(usrp_dict, -// pmt_intern("rf-freq"), -// pmt_from_long(10e6)); - - define_component("server", "usrp_server", usrp_dict); - - connect("self", "tx0", "server", "tx0"); - 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); - - // FIXME need to somehow set the interp rate in the USRP. - // for now, we'll have the low-level code hardwire it. -} - -test_usrp_tx::~test_usrp_tx() -{ -} - -void -test_usrp_tx::initial_transition() -{ - open_usrp(); -} - -void -test_usrp_tx::handle_message(mb_message_sptr msg) -{ - pmt_t event = msg->signal(); - pmt_t data = msg->data(); - - pmt_t handle = PMT_F; - pmt_t status = PMT_F; - std::string error_msg; - - //std::cout << msg << std::endl; - - switch(d_state){ - case OPENING_USRP: - if (pmt_eq(event, s_response_open)){ - status = pmt_nth(1, data); - if (pmt_eq(status, PMT_T)){ - allocate_channel(); - return; - } - else { - error_msg = "failed to open usrp:"; - goto bail; - } - } - goto unhandled; - - case ALLOCATING_CHANNEL: - if (pmt_eq(event, s_response_allocate_channel)){ - status = pmt_nth(1, data); - if(pmt_eqv(d_tx_chan0, PMT_NIL)) - d_tx_chan0 = pmt_nth(2, data); - else - d_tx_chan1 = pmt_nth(2, data); - - if (pmt_eq(status, PMT_T) && !pmt_eqv(d_tx_chan1, PMT_NIL)){ - enter_transmitting(); - return; - } - else if(pmt_eq(status, PMT_F)){ - error_msg = "failed to allocate channel:"; - goto bail; - } - return; - } - goto unhandled; - - case TRANSMITTING: - 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; - } - } - goto unhandled; - - case CLOSING_CHANNEL: - if (pmt_eq(event, s_response_deallocate_channel)){ - status = pmt_nth(1, data); - - if (pmt_eq(status, PMT_T)){ - close_usrp(); - return; - } - else { - error_msg = "failed to deallocate channel:"; - goto bail; - } - } - goto unhandled; - - case CLOSING_USRP: - if (pmt_eq(event, s_response_close)){ - status = pmt_nth(1, data); - - if (pmt_eq(status, PMT_T)){ - shutdown_all(PMT_T); - return; - } - else { - error_msg = "failed to close USRP:"; - goto bail; - } - } - goto unhandled; - - default: - goto unhandled; - } - return; - - bail: - std::cerr << error_msg << data - << "status = " << status << std::endl; - shutdown_all(PMT_F); - return; - - unhandled: - std::cout << "test_usrp_inband_tx: unhandled msg: " << msg - << "in state "<< d_state << std::endl; -} - - -void -test_usrp_tx::open_usrp() -{ - pmt_t which_usrp = pmt_from_long(0); - - d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, which_usrp)); - d_state = OPENING_USRP; - - if(verbose) - std::cout << "[TEST_USRP_INBAND_TX] Opening the USRP\n"; -} - -void -test_usrp_tx::close_usrp() -{ - d_cs->send(s_cmd_close, pmt_list1(PMT_NIL)); - d_state = CLOSING_USRP; - - if(verbose) - std::cout << "[TEST_USRP_INBAND_TX] Closing the USRP\n"; -} - -void -test_usrp_tx::allocate_channel() -{ - long capacity = (long) 16e6; - - // Send two capacity requests, which will allocate us two channels - d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity))); - d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity))); - d_state = ALLOCATING_CHANNEL; - - if(verbose) - std::cout << "[TEST_USRP_INBAND_TX] Requesting TX channel allocation\n"; -} - -void -test_usrp_tx::enter_transmitting() -{ - d_state = TRANSMITTING; - d_nsamples_xmitted = 0; - - if(verbose) - std::cout << "[TEST_USRP_INBAND_TX] Transmitting...\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_tx::build_and_send_next_frame() -{ - // allocate the uniform vector for the samples - // FIXME perhaps hold on to this between calls - -#if 1 - long nsamples_this_frame = - std::min(d_nsamples_to_send - d_nsamples_xmitted, - d_samples_per_frame); -#else - long nsamples_this_frame = d_samples_per_frame; -#endif - - 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_writable_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 tx_properties = pmt_make_dict(); - - pmt_t timestamp = pmt_from_long(0xffffffff); // NOW - d_tx->send(s_cmd_xmit_raw_frame, - pmt_list5(pmt_from_long(d_nframes_xmitted), // invocation-handle - d_tx_chan0, // channel - uvec, // the samples - timestamp, - tx_properties)); - - // Resend on channel 1 - d_tx->send(s_cmd_xmit_raw_frame, - pmt_list5(pmt_from_long(d_nframes_xmitted), // invocation-handle - d_tx_chan1, // channel - uvec, // the samples - timestamp, - tx_properties)); - - d_nsamples_xmitted += nsamples_this_frame; - d_nframes_xmitted++; - - if(verbose && 0) - std::cout << "[TEST_USRP_INBAND_TX] Transmitted frame\n"; -} - - -void -test_usrp_tx::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 - enter_closing_channel(); - } - - build_and_send_next_frame(); -} - -void -test_usrp_tx::enter_closing_channel() -{ - d_state = CLOSING_CHANNEL; - - // Deallocate both channels - d_tx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_tx_chan0)); - d_tx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_tx_chan1)); - - if(verbose) - std::cout << "[TEST_USRP_INBAND_tX] Deallocating TX channel\n"; -} - -REGISTER_MBLOCK_CLASS(test_usrp_tx); - - -// ---------------------------------------------------------------- - -int -main (int argc, char **argv) -{ - // handle any command line args here - - mb_runtime_sptr rt = mb_make_runtime(); - pmt_t result = PMT_NIL; - - rt->run("top", "test_usrp_tx", PMT_F, &result); -} diff --git a/usrp/limbo/apps-inband/test_usrp_inband_overrun.cc b/usrp/limbo/apps-inband/test_usrp_inband_overrun.cc deleted file mode 100644 index cd0fa525a..000000000 --- a/usrp/limbo/apps-inband/test_usrp_inband_overrun.cc +++ /dev/null @@ -1,375 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <mblock/mblock.h> -#include <mblock/runtime.h> -#include <mblock/protocol_class.h> -#include <mblock/exception.h> -#include <mblock/msg_queue.h> -#include <mblock/message.h> -#include <mblock/msg_accepter.h> -#include <mblock/class_registry.h> -#include <pmt.h> -#include <stdio.h> -#include <string.h> -#include <iostream> -#include <fstream> - -// Include the symbols needed for communication with USRP server -#include <symbols_usrp_server_cs.h> -#include <symbols_usrp_channel.h> -#include <symbols_usrp_low_level_cs.h> -#include <symbols_usrp_rx.h> - -static bool verbose = true; - -class test_usrp_rx : public mb_mblock -{ - mb_port_sptr d_rx; - mb_port_sptr d_cs; - pmt_t d_rx_chan; // returned tx channel handle - - enum state_t { - INIT, - OPENING_USRP, - ALLOCATING_CHANNEL, - RECEIVING, - CLOSING_CHANNEL, - CLOSING_USRP, - }; - - state_t d_state; - - std::ofstream d_ofile; - - long d_n_overruns; - - long d_samples_recvd; - long d_samples_to_recv; - - public: - test_usrp_rx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg); - ~test_usrp_rx(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - protected: - void open_usrp(); - void close_usrp(); - void allocate_channel(); - void send_packets(); - void enter_receiving(); - void build_and_send_next_frame(); - void handle_response_recv_raw_samples(pmt_t invocation_handle); - void enter_closing_channel(); -}; - -test_usrp_rx::test_usrp_rx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(runtime, instance_name, user_arg), - d_n_overruns(0), - d_samples_recvd(0), - d_samples_to_recv(10e6) -{ - - d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL); - d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL); - - // Pass a dictionary to usrp_server which specifies which interface to use, the stub or USRP - pmt_t usrp_dict = pmt_make_dict(); - - // Specify the RBF to use - pmt_dict_set(usrp_dict, - pmt_intern("rbf"), - pmt_intern("inband_1rxhb_1tx.rbf")); - - pmt_dict_set(usrp_dict, - pmt_intern("decim-rx"), - pmt_from_long(128)); - - define_component("server", "usrp_server", usrp_dict); - - connect("self", "rx0", "server", "rx0"); - connect("self", "cs", "server", "cs"); - -} - -test_usrp_rx::~test_usrp_rx() -{ -} - -void -test_usrp_rx::initial_transition() -{ - open_usrp(); -} - -void -test_usrp_rx::handle_message(mb_message_sptr msg) -{ - pmt_t event = msg->signal(); - pmt_t data = msg->data(); - - pmt_t handle = PMT_F; - pmt_t status = PMT_F; - std::string error_msg; - - switch(d_state){ - - //----------------------------- OPENING_USRP ----------------------------// - // We only expect a response from opening the USRP which should be succesful - // or failed. - case OPENING_USRP: - if (pmt_eq(event, s_response_open)){ - status = pmt_nth(1, data); - if (pmt_eq(status, PMT_T)){ - allocate_channel(); - return; - } - else { - error_msg = "failed to open usrp:"; - goto bail; - } - } - goto unhandled; - - //----------------------- ALLOCATING CHANNELS --------------------// - // Allocate an RX channel to perform the overrun test. - case ALLOCATING_CHANNEL: - if (pmt_eq(event, s_response_allocate_channel)){ - status = pmt_nth(1, data); - d_rx_chan = pmt_nth(2, data); - - if (pmt_eq(status, PMT_T)){ - enter_receiving(); - return; - } - else { - error_msg = "failed to allocate channel:"; - goto bail; - } - } - goto unhandled; - - //--------------------------- RECEIVING ------------------------------// - // In the receiving state, we receive samples until the specified amount - // while counting the number of overruns. - case RECEIVING: - if (pmt_eq(event, s_response_recv_raw_samples)){ - status = pmt_nth(1, data); - - if (pmt_eq(status, PMT_T)){ - handle_response_recv_raw_samples(data); - return; - } - else { - error_msg = "bad response-xmit-raw-frame:"; - goto bail; - } - } - goto unhandled; - - //------------------------- CLOSING CHANNEL ----------------------------// - // Check deallocation response for the RX channel - case CLOSING_CHANNEL: - if (pmt_eq(event, s_response_deallocate_channel)){ - status = pmt_nth(1, data); - - if (pmt_eq(status, PMT_T)){ - close_usrp(); - return; - } - else { - error_msg = "failed to deallocate channel:"; - goto bail; - } - } - - // Alternately, we ignore all response recv samples while waiting for the - // channel to actually close - if (pmt_eq(event, s_response_recv_raw_samples)) - return; - - 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)){ - std::cout << "\nOverruns: " << d_n_overruns << std::endl; - fflush(stdout); - shutdown_all(PMT_T); - return; - } - else { - error_msg = "failed to close USRP:"; - goto bail; - } - } - goto unhandled; - - default: - goto unhandled; - } - return; - - // An error occured, print it, and shutdown all m-blocks - bail: - std::cerr << error_msg << data - << "status = " << status << std::endl; - shutdown_all(PMT_F); - return; - - // Received an unhandled message for a specific state - unhandled: - if(verbose && !pmt_eq(event, pmt_intern("%shutdown"))) - std::cout << "test_usrp_inband_tx: unhandled msg: " << msg - << "in state "<< d_state << std::endl; -} - - -void -test_usrp_rx::open_usrp() -{ - pmt_t which_usrp = pmt_from_long(0); - - d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, which_usrp)); - d_state = OPENING_USRP; - - if(verbose) - std::cout << "[TEST_USRP_INBAND_OVERRUN] Opening the USRP\n"; -} - -void -test_usrp_rx::close_usrp() -{ - d_cs->send(s_cmd_close, pmt_list1(PMT_NIL)); - d_state = CLOSING_USRP; - - if(verbose) - std::cout << "[TEST_USRP_INBAND_OVERRUN] Closing the USRP\n"; -} - -void -test_usrp_rx::allocate_channel() -{ - long capacity = (long) 16e6; - d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity))); - d_state = ALLOCATING_CHANNEL; - - if(verbose) - std::cout << "[TEST_USRP_INBAND_OVERRUN] Requesting RX channel allocation\n"; -} - -void -test_usrp_rx::enter_receiving() -{ - d_state = RECEIVING; - - d_rx->send(s_cmd_start_recv_raw_samples, - pmt_list2(PMT_F, - d_rx_chan)); - - if(verbose) - std::cout << "[TEST_USRP_INBAND_OVERRUN] Receiving...\n"; -} - -void -test_usrp_rx::handle_response_recv_raw_samples(pmt_t data) -{ - pmt_t invocation_handle = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - pmt_t v_samples = pmt_nth(2, data); - pmt_t timestamp = pmt_nth(3, data); - pmt_t channel = pmt_nth(4, data); - pmt_t properties = pmt_nth(5, data); - - d_samples_recvd += pmt_length(v_samples) / 4; - - // Check for overrun - if(!pmt_is_dict(properties)) { - std::cout << "[TEST_USRP_INBAND_OVERRUN] Recv samples dictionary is improper\n"; - return; - } - - if(pmt_t overrun = pmt_dict_ref(properties, - pmt_intern("overrun"), - PMT_NIL)) { - if(pmt_eqv(overrun, PMT_T)) { - d_n_overruns++; - - if(verbose && 0) - std::cout << "[TEST_USRP_INBAND_OVERRUN] Underrun\n"; - } - else { - if(verbose && 0) - std::cout << "[TEST_USRP_INBAND_OVERRUN] No overrun\n" << overrun <<std::endl; - } - } else { - - if(verbose && 0) - std::cout << "[TEST_USRP_INBAND_OVERRUN] No overrun\n"; - } - - // Check if the number samples we have received meets the test - if(d_samples_recvd >= d_samples_to_recv) { - d_rx->send(s_cmd_stop_recv_raw_samples, pmt_list2(PMT_NIL, d_rx_chan)); - enter_closing_channel(); - return; - } - -} - -void -test_usrp_rx::enter_closing_channel() -{ - d_state = CLOSING_CHANNEL; - - sleep(2); - - d_rx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_rx_chan)); - - if(verbose) - std::cout << "[TEST_USRP_INBAND_OVERRUN] Deallocating RX channel\n"; -} - -REGISTER_MBLOCK_CLASS(test_usrp_rx); - - -// ---------------------------------------------------------------- - -int -main (int argc, char **argv) -{ - // handle any command line args here - - mb_runtime_sptr rt = mb_make_runtime(); - pmt_t result = PMT_NIL; - - rt->run("top", "test_usrp_rx", PMT_F, &result); -} diff --git a/usrp/limbo/apps-inband/test_usrp_inband_ping.cc b/usrp/limbo/apps-inband/test_usrp_inband_ping.cc deleted file mode 100644 index d779c9a64..000000000 --- a/usrp/limbo/apps-inband/test_usrp_inband_ping.cc +++ /dev/null @@ -1,374 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <mblock/mblock.h> -#include <mblock/runtime.h> -#include <mblock/protocol_class.h> -#include <mblock/exception.h> -#include <mblock/msg_queue.h> -#include <mblock/message.h> -#include <mblock/msg_accepter.h> -#include <mblock/class_registry.h> -#include <pmt.h> -#include <stdio.h> -#include <string.h> -#include <sys/time.h> -#include <iostream> - -// Include the symbols needed for communication with USRP server -#include <symbols_usrp_server_cs.h> -#include <symbols_usrp_channel.h> -#include <symbols_usrp_low_level_cs.h> -#include <symbols_usrp_tx.h> -#include <symbols_usrp_rx.h> - -static bool verbose = false; - -class test_usrp_inband_ping : public mb_mblock -{ - - mb_port_sptr d_tx; // Ports connected to the USRP server - mb_port_sptr d_rx; - mb_port_sptr d_cs; - - pmt_t d_tx_chan; // Returned channel from TX allocation - pmt_t d_rx_chan; // Returned channel from RX allocation - - pmt_t d_which_usrp; // The USRP to use for the test - - long d_warm_msgs; // The number of messages to 'warm' the USRP - long d_warm_recvd; // The number of msgs received in the 'warm' state - - // Keep track of current state - enum state_t { - INIT, - OPENING_USRP, - ALLOCATING_CHANNELS, - WARMING_USRP, - PINGING, - CLOSING_CHANNELS, - CLOSING_USRP, - }; - state_t d_state; - - public: - test_usrp_inband_ping(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg); - ~test_usrp_inband_ping(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - protected: - void opening_usrp(); - void allocating_channels(); - void enter_warming_usrp(); - void enter_pinging(); - void build_and_send_ping(); - void closing_channels(); - void closing_usrp(); -}; - - -int -main (int argc, char **argv) -{ - // handle any command line args here - - mb_runtime_sptr rt = mb_make_runtime(); - pmt_t result = PMT_NIL; - - rt->run("top", "test_usrp_inband_ping", PMT_F, &result); -} - - -test_usrp_inband_ping::test_usrp_inband_ping(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(runtime, instance_name, user_arg), - d_tx_chan(PMT_NIL), - d_rx_chan(PMT_NIL), - d_which_usrp(pmt_from_long(0)), - d_state(INIT) -{ - - // A dictionary is used to pass parameters to the USRP - pmt_t usrp_dict = pmt_make_dict(); - - // Specify the RBF to use - pmt_dict_set(usrp_dict, - pmt_intern("rbf"), - pmt_intern("fixed1.rbf")); - - // Set TX and RX interpolations - pmt_dict_set(usrp_dict, - pmt_intern("interp-tx"), - pmt_from_long(128)); - - pmt_dict_set(usrp_dict, - pmt_intern("decim-rx"), - pmt_from_long(16)); - - d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL); - d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL); - d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL); - - // Create an instance of USRP server and connect ports - define_component("server", "usrp_server", usrp_dict); - connect("self", "tx0", "server", "tx0"); - connect("self", "rx0", "server", "rx0"); - connect("self", "cs", "server", "cs"); - -} - -test_usrp_inband_ping::~test_usrp_inband_ping() -{ -} - -void -test_usrp_inband_ping::initial_transition() -{ - opening_usrp(); -} - -// Handle message reads all incoming messages from USRP server which will be -// initialization and ping responses. We perform actions based on the current -// state and the event (ie, ping response) -void -test_usrp_inband_ping::handle_message(mb_message_sptr msg) -{ - pmt_t event = msg->signal(); - pmt_t data = msg->data(); - pmt_t port_id = msg->port_id(); - - pmt_t handle = PMT_F; - pmt_t status = PMT_F; - std::string error_msg; - - // Dispatch based on state - switch(d_state) { - - //----------------------------- OPENING_USRP ----------------------------// - // We only expect a response from opening the USRP which should be succesful - // or failed. - case OPENING_USRP: - - if(pmt_eq(event, s_response_open)) { - - status = pmt_nth(1, data); // failed/succes - - if(pmt_eq(status, PMT_T)) { - allocating_channels(); - return; - } - else { - error_msg = "failed to open usrp:"; - goto bail; - } - - } - - goto unhandled; // all other messages not handled in this state - - - //----------------------- ALLOCATING CHANNELS --------------------// - // When allocating channels, we need to wait for 2 responses from - // USRP server: one for TX and one for RX. Both are initialized to - // NIL so we know to continue to the next state once both are set. - case ALLOCATING_CHANNELS: - - // A TX allocation response - if(pmt_eq(event, s_response_allocate_channel) - && pmt_eq(d_tx->port_symbol(), port_id)) - { - status = pmt_nth(1, data); - - // If successful response, extract the channel - if(pmt_eq(status, PMT_T)) { - - d_tx_chan = pmt_nth(2, data); - - if(verbose) - std::cout << "[TEST_USRP_INBAND_PING] 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_warming_usrp(); - - return; - } - else { // TX allocation failed - error_msg = "failed to allocate TX channel:"; - goto bail; - } - } - - // A RX allocation response - if(pmt_eq(event, s_response_allocate_channel) - && pmt_eq(d_rx->port_symbol(), port_id)) - { - status = pmt_nth(1, data); - - // If successful response, extract the channel - if(pmt_eq(status, PMT_T)) { - - d_rx_chan = pmt_nth(2, data); - - if(verbose) - std::cout << "[TEST_USRP_INBAND_PING] 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_warming_usrp(); - - return; - } - else { // RX allocation failed - error_msg = "failed to allocate RX channel:"; - goto bail; - } - } - - goto unhandled; - - //----------------------- WARMING USRP --------------------// - // The FX2 seems to need some amount of data to be buffered - // before it begins reading. We use this state to simply - // warm up the USRP before benchmarking pings. - case WARMING_USRP: - - // We really don't care about the responses from the - // control channel in the warming stage, but once we receive - // the proper number of responses we switch states. - if(pmt_eq(event, s_response_from_control_channel) - && pmt_eq(d_rx->port_symbol(), port_id)) - { - d_warm_recvd++; - - if(d_warm_recvd > d_warm_msgs) - enter_pinging(); - - return; - } - - goto unhandled; - - case PINGING: - goto unhandled; - - case CLOSING_CHANNELS: - goto unhandled; - - case CLOSING_USRP: - goto unhandled; - - case INIT: - goto unhandled; - - } - - // An error occured, print it, and shutdown all m-blocks - bail: - std::cerr << error_msg << data - << "status = " << status << std::endl; - shutdown_all(PMT_F); - return; - - // Received an unhandled message for a specific state - unhandled: - if(verbose) - std::cout << "test_usrp_inband_tx: unhandled msg: " << msg - << "in state "<< d_state << std::endl; - -} - - -// Sends a command to USRP server to open up a connection to the -// specified USRP, which is defaulted to USRP 0 on the system -void -test_usrp_inband_ping::opening_usrp() -{ - - if(verbose) - std::cout << "[TEST_USRP_INBAND_PING] Opening USRP " - << d_which_usrp << std::endl; - - d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, d_which_usrp)); - d_state = OPENING_USRP; -} - -// RX and TX channels must be allocated so that the USRP server can -// properly share bandwidth across multiple USRPs. No commands will be -// successful to the USRP through the USRP server on the TX or RX channels until -// a bandwidth allocation has been received. -void -test_usrp_inband_ping::allocating_channels() -{ - d_state = ALLOCATING_CHANNELS; - - long capacity = (long) 16e6; - d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity))); - d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity))); -} - -// The USRP needs some amount of initial data to pass a buffering point such -// that it begins to pull and read data from the FX2. We send an arbitrary -// amount of data to start the pipeline, which are just pings. -void -test_usrp_inband_ping::enter_warming_usrp() -{ - d_state = WARMING_USRP; - - for(int i=0; i < d_warm_msgs; i++) - build_and_send_ping(); -} - -void -test_usrp_inband_ping::enter_pinging() -{ - d_state = PINGING; - - if(verbose) - std::cout << "[TEST_USRP_INBAND_PING] Running ping tests\n"; - -} - -// Pings are sent over the TX channel using the signal 'cmd-to-control-channel' -// to the USRP server. Within this message there can be infinite subpackets -// stored as a list (the second parameter) and sent. The only subpacket we send -// is a ping, interpreted by the 'op-ping-fixed' signal. -void -test_usrp_inband_ping::build_and_send_ping() -{ - - d_tx->send(s_cmd_to_control_channel, // USRP server signal - pmt_list2(PMT_NIL, // invocation handle - pmt_list1(pmt_list3(s_op_ping_fixed, - pmt_from_long(0), - pmt_from_long(0))))); - - if(verbose) - std::cout << "[TEST_USRP_INBAND_PING] Ping!!" << std::endl; -} - -REGISTER_MBLOCK_CLASS(test_usrp_inband_ping); diff --git a/usrp/limbo/apps-inband/test_usrp_inband_registers.cc b/usrp/limbo/apps-inband/test_usrp_inband_registers.cc deleted file mode 100644 index d9bd2db17..000000000 --- a/usrp/limbo/apps-inband/test_usrp_inband_registers.cc +++ /dev/null @@ -1,435 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <mblock/mblock.h> -#include <mblock/runtime.h> -#include <mblock/protocol_class.h> -#include <mblock/exception.h> -#include <mblock/msg_queue.h> -#include <mblock/message.h> -//#include <mb_mblock_impl.h> -#include <mblock/msg_accepter.h> -#include <mblock/class_registry.h> -#include <pmt.h> -#include <stdio.h> -#include <string.h> -#include <sys/time.h> -#include <iostream> - -// Include the symbols needed for communication with USRP server -#include <symbols_usrp_server_cs.h> -#include <symbols_usrp_channel.h> -#include <symbols_usrp_low_level_cs.h> -#include <symbols_usrp_tx.h> -#include <symbols_usrp_rx.h> - -static bool verbose = true; - -class test_usrp_inband_registers : public mb_mblock -{ - - mb_port_sptr d_tx; // Ports connected to the USRP server - mb_port_sptr d_rx; - mb_port_sptr d_cs; - - pmt_t d_tx_chan; // Returned channel from TX allocation - pmt_t d_rx_chan; // Returned channel from RX allocation - - pmt_t d_which_usrp; // The USRP to use for the test - - long d_warm_msgs; // The number of messages to 'warm' the USRP - long d_warm_recvd; // The number of msgs received in the 'warm' state - - // Keep track of current state - enum state_t { - INIT, - OPENING_USRP, - ALLOCATING_CHANNELS, - WRITE_REGISTER, - READ_REGISTER, - CLOSING_CHANNELS, - CLOSING_USRP, - }; - state_t d_state; - - public: - test_usrp_inband_registers(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg); - ~test_usrp_inband_registers(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - protected: - void opening_usrp(); - void allocating_channels(); - void write_register(); - void read_register(); - void closing_channels(); - void closing_usrp(); - void enter_receiving(); - void build_and_send_ping(); -}; - - -int -main (int argc, char **argv) -{ - // handle any command line args here - - mb_runtime_sptr rt = mb_make_runtime(); - pmt_t result = PMT_NIL; - - rt->run("top", "test_usrp_inband_registers", PMT_F, &result); -} - - -test_usrp_inband_registers::test_usrp_inband_registers(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(runtime, instance_name, user_arg), - d_tx_chan(PMT_NIL), - d_rx_chan(PMT_NIL), - d_which_usrp(pmt_from_long(0)), - d_state(INIT) -{ - - // A dictionary is used to pass parameters to the USRP - pmt_t usrp_dict = pmt_make_dict(); - - // Specify the RBF to use - pmt_dict_set(usrp_dict, - pmt_intern("rbf"), - pmt_intern("inband_1rxhb_1tx.rbf")); - - // Set TX and RX interpolations - pmt_dict_set(usrp_dict, - pmt_intern("interp-tx"), - pmt_from_long(128)); - - pmt_dict_set(usrp_dict, - pmt_intern("decim-rx"), - pmt_from_long(16)); - - d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL); - d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL); - d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL); - - // Create an instance of USRP server and connect ports - define_component("server", "usrp_server", usrp_dict); - connect("self", "tx0", "server", "tx0"); - connect("self", "rx0", "server", "rx0"); - connect("self", "cs", "server", "cs"); - -} - -test_usrp_inband_registers::~test_usrp_inband_registers() -{ -} - -void -test_usrp_inband_registers::initial_transition() -{ - opening_usrp(); -} - -// Handle message reads all incoming messages from USRP server which will be -// initialization and ping responses. We perform actions based on the current -// state and the event (ie, ping response) -void -test_usrp_inband_registers::handle_message(mb_message_sptr msg) -{ - pmt_t event = msg->signal(); - pmt_t data = msg->data(); - pmt_t port_id = msg->port_id(); - - pmt_t handle = PMT_F; - pmt_t status = PMT_F; - std::string error_msg; - - // Dispatch based on state - switch(d_state) { - - //----------------------------- OPENING_USRP ----------------------------// - // We only expect a response from opening the USRP which should be succesful - // or failed. - case OPENING_USRP: - - if(pmt_eq(event, s_response_open)) { - - status = pmt_nth(1, data); // failed/succes - - if(pmt_eq(status, PMT_T)) { - allocating_channels(); - return; - } - else { - error_msg = "failed to open usrp:"; - goto bail; - } - - } - - goto unhandled; // all other messages not handled in this state - - - //----------------------- ALLOCATING CHANNELS --------------------// - // When allocating channels, we need to wait for 2 responses from - // USRP server: one for TX and one for RX. Both are initialized to - // NIL so we know to continue to the next state once both are set. - case ALLOCATING_CHANNELS: - - // A TX allocation response - if(pmt_eq(event, s_response_allocate_channel) - && pmt_eq(d_tx->port_symbol(), port_id)) - { - status = pmt_nth(1, data); - - // If successful response, extract the channel - if(pmt_eq(status, PMT_T)) { - - d_tx_chan = pmt_nth(2, data); - - if(verbose) - std::cout << "[TEST_USRP_INBAND_PING] 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(); - } - - return; - } - else { // TX allocation failed - error_msg = "failed to allocate TX channel:"; - goto bail; - } - } - - // A RX allocation response - if(pmt_eq(event, s_response_allocate_channel) - && pmt_eq(d_rx->port_symbol(), port_id)) - { - status = pmt_nth(1, data); - - // If successful response, extract the channel - if(pmt_eq(status, PMT_T)) { - - d_rx_chan = pmt_nth(2, data); - - if(verbose) - std::cout << "[TEST_USRP_INBAND_PING] 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(); - } - - return; - } - else { // RX allocation failed - error_msg = "failed to allocate RX channel:"; - goto bail; - } - } - - 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: - - if(pmt_eq(event, s_response_from_control_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(pmt_eq(status, PMT_T)) { - - pmt_t subp = pmt_nth(2, data); // subpacket should be the read reg reply - - pmt_t subp_sig = pmt_nth(0, subp); - pmt_t subp_data = pmt_nth(1, subp); - - if(!pmt_eqv(subp_sig, s_op_read_reg_reply)) { - error_msg = "received improper subpacket when expecting reg reply."; - goto bail; - } - - 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); - - 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 - return; - - } else { // bail on unsuccessful write - error_msg = "failed to write to register."; - goto bail; - } - } - goto unhandled; - - case CLOSING_CHANNELS: - goto unhandled; - - case CLOSING_USRP: - goto unhandled; - - case INIT: - goto unhandled; - - } - - // An error occured, print it, and shutdown all m-blocks - bail: - std::cerr << error_msg << data - << "status = " << status << std::endl; - shutdown_all(PMT_F); - return; - - // Received an unhandled message for a specific state - unhandled: - if(verbose && !pmt_eq(event, s_response_recv_raw_samples)) - std::cout << "test_usrp_inband_tx: unhandled msg: " << msg - << "in state "<< d_state << std::endl; - -} - - -// Sends a command to USRP server to open up a connection to the -// specified USRP, which is defaulted to USRP 0 on the system -void -test_usrp_inband_registers::opening_usrp() -{ - - if(verbose) - std::cout << "[TEST_USRP_INBAND_PING] Opening USRP " - << d_which_usrp << std::endl; - - d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, d_which_usrp)); - d_state = OPENING_USRP; -} - -// RX and TX channels must be allocated so that the USRP server can -// properly share bandwidth across multiple USRPs. No commands will be -// successful to the USRP through the USRP server on the TX or RX channels until -// a bandwidth allocation has been received. -void -test_usrp_inband_registers::allocating_channels() -{ - d_state = ALLOCATING_CHANNELS; - - long capacity = (long) 16e6; - d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity))); - d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity))); -} - -// After allocating the channels, a write register command will be sent to the -// USRP. -void -test_usrp_inband_registers::write_register() -{ - d_state = WRITE_REGISTER; - - long reg = 0; - - d_tx->send(s_cmd_to_control_channel, // C/S packet - pmt_list2(PMT_NIL, // invoc handle - pmt_list1( - pmt_list2(s_op_write_reg, - pmt_list2( - pmt_from_long(reg), - pmt_from_long(0xbeef)))))); - - if(verbose) - std::cout << "[TEST_USRP_INBAND_REGISTERS] Writing 0xbeef to " - << reg << std::endl; - - read_register(); // immediately transition to read the register -} - -// Temporary: for testing pings -void -test_usrp_inband_registers::build_and_send_ping() -{ - - d_tx->send(s_cmd_to_control_channel, - pmt_list2(PMT_NIL, pmt_list1(pmt_list2(s_op_ping_fixed, - pmt_list2(pmt_from_long(0), - pmt_from_long(0)))))); - - std::cout << "[TEST_USRP_INBAND_CS] Ping sent" << std::endl; -} - -// After writing to the register, we want to read the value back and ensure that -// it is the same value that we wrote. -void -test_usrp_inband_registers::read_register() -{ - d_state = READ_REGISTER; - - long reg = 9; - - d_tx->send(s_cmd_to_control_channel, // C/S packet - pmt_list2(PMT_NIL, // invoc handle - pmt_list1( - pmt_list2(s_op_read_reg, - pmt_list2( - pmt_from_long(0), // rid - pmt_from_long(reg)))))); - if(verbose) - std::cout << "[TEST_USRP_INBAND_REGISTERS] Reading from register " - << reg << std::endl; -} - -// Used to enter the receiving state -void -test_usrp_inband_registers::enter_receiving() -{ - d_rx->send(s_cmd_start_recv_raw_samples, - pmt_list2(PMT_F, - d_rx_chan)); -} - -REGISTER_MBLOCK_CLASS(test_usrp_inband_registers); diff --git a/usrp/limbo/apps-inband/test_usrp_inband_rx.cc b/usrp/limbo/apps-inband/test_usrp_inband_rx.cc deleted file mode 100644 index 4f21e4afc..000000000 --- a/usrp/limbo/apps-inband/test_usrp_inband_rx.cc +++ /dev/null @@ -1,362 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <mblock/mblock.h> -#include <mblock/runtime.h> -#include <mblock/protocol_class.h> -#include <mblock/exception.h> -#include <mblock/msg_queue.h> -#include <mblock/message.h> -#include <mblock/msg_accepter.h> -#include <mblock/class_registry.h> -#include <pmt.h> -#include <stdio.h> -#include <string.h> -#include <iostream> -#include <fstream> - -// Include the symbols needed for communication with USRP server -#include <symbols_usrp_server_cs.h> -#include <symbols_usrp_channel.h> -#include <symbols_usrp_low_level_cs.h> -#include <symbols_usrp_rx.h> - -static bool verbose = true; - -class test_usrp_rx : public mb_mblock -{ - mb_port_sptr d_rx; - mb_port_sptr d_cs; - pmt_t d_rx_chan; // returned tx channel handle - - enum state_t { - INIT, - OPENING_USRP, - ALLOCATING_CHANNEL, - RECEIVING, - CLOSING_CHANNEL, - CLOSING_USRP, - }; - - state_t d_state; - - std::ofstream d_ofile; - - long d_samples_recvd; - long d_samples_to_recv; - - public: - test_usrp_rx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg); - ~test_usrp_rx(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - protected: - void open_usrp(); - void close_usrp(); - void allocate_channel(); - void send_packets(); - void enter_receiving(); - void build_and_send_next_frame(); - void handle_response_recv_raw_samples(pmt_t invocation_handle); - void enter_closing_channel(); -}; - -test_usrp_rx::test_usrp_rx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(runtime, instance_name, user_arg), - d_samples_recvd(0), - d_samples_to_recv(20e6) -{ - d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL); - d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL); - - // Pass a dictionary to usrp_server which specifies which interface to use, the stub or USRP - pmt_t usrp_dict = pmt_make_dict(); - - // To test the application without a USRP - bool fake_usrp_p = false; - if(fake_usrp_p) { - pmt_dict_set(usrp_dict, - pmt_intern("fake-usrp"), - PMT_T); - } - - // Specify the RBF to use - pmt_dict_set(usrp_dict, - pmt_intern("rbf"), - pmt_intern("inband_1rxhb_1tx.rbf")); - - pmt_dict_set(usrp_dict, - pmt_intern("decim-rx"), - pmt_from_long(64)); - -// If unspecified, chooses center frequency from range -// pmt_dict_set(usrp_dict, -// pmt_intern("rf-freq"), -// pmt_from_long(10e6)); - - define_component("server", "usrp_server", usrp_dict); - - connect("self", "rx0", "server", "rx0"); - connect("self", "cs", "server", "cs"); - -} - -test_usrp_rx::~test_usrp_rx() -{ -} - -void -test_usrp_rx::initial_transition() -{ - open_usrp(); -} - -void -test_usrp_rx::handle_message(mb_message_sptr msg) -{ - pmt_t event = msg->signal(); - pmt_t data = msg->data(); - - pmt_t handle = PMT_F; - pmt_t status = PMT_F; - std::string error_msg; - - switch(d_state){ - - //----------------------------- OPENING_USRP ----------------------------// - // We only expect a response from opening the USRP which should be succesful - // or failed. - case OPENING_USRP: - if (pmt_eq(event, s_response_open)){ - status = pmt_nth(1, data); - if (pmt_eq(status, PMT_T)){ - allocate_channel(); - return; - } - else { - error_msg = "failed to open usrp:"; - goto bail; - } - } - goto unhandled; - - //----------------------- ALLOCATING CHANNELS --------------------// - // Allocate an RX channel to perform the overrun test. - case ALLOCATING_CHANNEL: - if (pmt_eq(event, s_response_allocate_channel)){ - status = pmt_nth(1, data); - d_rx_chan = pmt_nth(2, data); - - if (pmt_eq(status, PMT_T)){ - enter_receiving(); - return; - } - else { - error_msg = "failed to allocate channel:"; - goto bail; - } - } - goto unhandled; - - //--------------------------- RECEIVING ------------------------------// - // In the receiving state, we receive samples until the specified amount - // while counting the number of overruns. - case RECEIVING: - if (pmt_eq(event, s_response_recv_raw_samples)){ - status = pmt_nth(1, data); - - if (pmt_eq(status, PMT_T)){ - handle_response_recv_raw_samples(data); - return; - } - else { - error_msg = "bad response-xmit-raw-frame:"; - goto bail; - } - } - goto unhandled; - - //------------------------- CLOSING CHANNEL ----------------------------// - // Check deallocation response for the RX channel - case CLOSING_CHANNEL: - if (pmt_eq(event, s_response_deallocate_channel)){ - status = pmt_nth(1, data); - - if (pmt_eq(status, PMT_T)){ - close_usrp(); - return; - } - else { - error_msg = "failed to deallocate channel:"; - goto bail; - } - } - - // Alternately, we ignore all response recv samples while waiting for the - // channel to actually close - if (pmt_eq(event, s_response_recv_raw_samples)) - return; - - 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)){ - fflush(stdout); - shutdown_all(PMT_T); - return; - } - else { - error_msg = "failed to close USRP:"; - goto bail; - } - } - goto unhandled; - - default: - goto unhandled; - } - return; - - // An error occured, print it, and shutdown all m-blocks - bail: - std::cerr << error_msg << data - << "status = " << status << std::endl; - shutdown_all(PMT_F); - return; - - // Received an unhandled message for a specific state - unhandled: - if(verbose && !pmt_eq(event, pmt_intern("%shutdown"))) - std::cout << "test_usrp_inband_tx: unhandled msg: " << msg - << "in state "<< d_state << std::endl; -} - - -void -test_usrp_rx::open_usrp() -{ - pmt_t which_usrp = pmt_from_long(0); - - d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, which_usrp)); - d_state = OPENING_USRP; - - if(verbose) - std::cout << "[TEST_USRP_INBAND_RX] Opening the USRP\n"; -} - -void -test_usrp_rx::close_usrp() -{ - - d_cs->send(s_cmd_close, pmt_list1(PMT_NIL)); - d_state = CLOSING_USRP; - - if(verbose) - std::cout << "[TEST_USRP_INBAND_RX] Closing the USRP\n"; -} - -void -test_usrp_rx::allocate_channel() -{ - long capacity = (long) 16e6; - d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity))); - d_state = ALLOCATING_CHANNEL; - - if(verbose) - std::cout << "[TEST_USRP_INBAND_RX] Requesting RX channel allocation\n"; -} - -void -test_usrp_rx::enter_receiving() -{ - d_state = RECEIVING; - - d_rx->send(s_cmd_start_recv_raw_samples, - pmt_list2(PMT_F, - d_rx_chan)); - - if(verbose) - std::cout << "[TEST_USRP_INBAND_RX] Receiving...\n"; -} - -void -test_usrp_rx::handle_response_recv_raw_samples(pmt_t data) -{ - pmt_t invocation_handle = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - pmt_t v_samples = pmt_nth(2, data); - pmt_t timestamp = pmt_nth(3, data); - pmt_t channel = pmt_nth(4, data); - pmt_t properties = pmt_nth(5, data); - - d_samples_recvd += pmt_length(v_samples) / 4; - - // Check for overrun - if(!pmt_is_dict(properties)) { - std::cout << "[TEST_USRP_INBAND_RX] Recv samples dictionary is improper\n"; - return; - } - - // Check if the number samples we have received meets the test - if(d_samples_recvd >= d_samples_to_recv) { - d_rx->send(s_cmd_stop_recv_raw_samples, pmt_list2(PMT_NIL, d_rx_chan)); - enter_closing_channel(); - return; - } - -} - -void -test_usrp_rx::enter_closing_channel() -{ - d_state = CLOSING_CHANNEL; - - d_rx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_rx_chan)); - - if(verbose) - std::cout << "[TEST_USRP_INBAND_RX] Deallocating RX channel\n"; -} - -REGISTER_MBLOCK_CLASS(test_usrp_rx); - - -// ---------------------------------------------------------------- - -int -main (int argc, char **argv) -{ - mb_runtime_sptr rt = mb_make_runtime(); - pmt_t result = PMT_NIL; - - rt->run("top", "test_usrp_rx", PMT_F, &result); - -} diff --git a/usrp/limbo/apps-inband/test_usrp_inband_timestamps.cc b/usrp/limbo/apps-inband/test_usrp_inband_timestamps.cc deleted file mode 100644 index 3b874d1a5..000000000 --- a/usrp/limbo/apps-inband/test_usrp_inband_timestamps.cc +++ /dev/null @@ -1,506 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <mblock/mblock.h> -#include <mblock/runtime.h> -#include <mblock/protocol_class.h> -#include <mblock/exception.h> -#include <mblock/msg_queue.h> -#include <mblock/message.h> -#include <mblock/msg_accepter.h> -#include <mblock/class_registry.h> -#include <pmt.h> -#include <stdio.h> -#include <string.h> -#include <sys/time.h> -#include <iostream> - -#include <ui_nco.h> -#include <symbols_usrp_server_cs.h> -#include <symbols_usrp_channel.h> -#include <symbols_usrp_low_level_cs.h> -#include <symbols_usrp_tx.h> -#include <symbols_usrp_rx.h> - -#define NBPING 10 - -static bool verbose = true; -bool bskip = false; -long bstep = 10000; -long bcurr = 0; -long incr = 0x500; -long ptime = 0x000; - -class test_usrp_inband_timestamps : public mb_mblock -{ - mb_port_sptr d_tx; - mb_port_sptr d_rx; - mb_port_sptr d_cs; - pmt_t d_tx_chan; // returned tx channel handle - pmt_t d_rx_chan; // returned tx channel handle - - struct timeval times[NBPING]; - - enum state_t { - INIT, - OPENING_USRP, - ALLOCATING_CHANNEL, - TRANSMITTING, - CLOSING_CHANNEL, - 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; - - public: - test_usrp_inband_timestamps(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg); - ~test_usrp_inband_timestamps(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - protected: - void open_usrp(); - void close_usrp(); - void allocate_channel(); - void send_packets(); - void enter_receiving(); - void enter_transmitting(); - void build_and_send_ping(); - void build_and_send_next_frame(); - void handle_xmit_response(pmt_t invocation_handle); - void enter_closing_channel(); -}; - -test_usrp_inband_timestamps::test_usrp_inband_timestamps(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(runtime, instance_name, user_arg), - d_tx_chan(PMT_NIL), - d_rx_chan(PMT_NIL), - d_state(INIT), d_nsamples_to_send((long) 40e6), - d_nsamples_xmitted(0), - d_nframes_xmitted(0), - //d_samples_per_frame((long)(126)), - d_samples_per_frame((long)(126 * 2)), // non-full packet - //d_samples_per_frame((long)(126 * 3.5)), // non-full packet - //d_samples_per_frame((long)(126 * 4)), // full packet - d_done_sending(false), - d_amplitude(16384) -{ - if(verbose) - std::cout << "[TEST_USRP_INBAND_TIMESTAMPS] Initializing...\n"; - - d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL); - d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL); - d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL); - - bool fake_usrp_p = false; - - // Test the TX side - - pmt_t usrp_dict = pmt_make_dict(); - - if(fake_usrp_p) { - pmt_dict_set(usrp_dict, - pmt_intern("fake-usrp"), - PMT_T); - } - - // Set TX and RX interpolations - pmt_dict_set(usrp_dict, - pmt_intern("interp-tx"), - pmt_from_long(128)); - - pmt_dict_set(usrp_dict, - pmt_intern("decim-rx"), - pmt_from_long(16)); - - // Specify the RBF to use - pmt_dict_set(usrp_dict, - pmt_intern("rbf"), - pmt_intern("inband_1rxhb_1tx.rbf")); - - define_component("server", "usrp_server", usrp_dict); - - connect("self", "tx0", "server", "tx0"); - 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_timestamps::~test_usrp_inband_timestamps() -{ -} - -void -test_usrp_inband_timestamps::initial_transition() -{ - open_usrp(); -} - -void -test_usrp_inband_timestamps::handle_message(mb_message_sptr msg) -{ - pmt_t event = msg->signal(); - pmt_t data = msg->data(); - pmt_t port_id = msg->port_id(); - - pmt_t handle = PMT_F; - pmt_t status = PMT_F; - std::string error_msg; - - //std::cout << msg << std::endl; - - switch(d_state){ - case OPENING_USRP: - if (pmt_eq(event, s_response_open)){ - status = pmt_nth(1, data); - if (pmt_eq(status, PMT_T)){ - allocate_channel(); - return; - } - else { - error_msg = "failed to open usrp:"; - goto bail; - } - } - goto unhandled; - - case ALLOCATING_CHANNEL: - if (pmt_eq(event, s_response_allocate_channel)){ - - if(pmt_eq(d_tx->port_symbol(), port_id)) { - status = pmt_nth(1, data); - d_tx_chan = pmt_nth(2, data); - - if (pmt_eq(status, PMT_T)){ - - if(verbose) - std::cout << "[TEST_USRP_INBAND_TIMESTAMPS] Received allocation for TX\n"; - - if(!pmt_eqv(d_rx_chan, PMT_NIL)) { - enter_receiving(); - enter_transmitting(); - } - return; - } - else { - error_msg = "failed to allocate channel:"; - goto bail; - } - } - - if(pmt_eq(d_rx->port_symbol(), port_id)) { - status = pmt_nth(1, data); - d_rx_chan = pmt_nth(2, data); - - if (pmt_eq(status, PMT_T)){ - - if(verbose) - std::cout << "[TEST_USRP_INBAND_TIMESTAMPS] Received allocation for TX\n"; - - if(!pmt_eqv(d_tx_chan, PMT_NIL)) { - enter_receiving(); - enter_transmitting(); - } - return; - } - else { - error_msg = "failed to allocate channel:"; - goto bail; - } - } - } - goto unhandled; - - case TRANSMITTING: - 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; - } - } - - if (pmt_eq(event, s_response_from_control_channel)) { - std::cout << "ping response!\n"; - } - goto unhandled; - - case CLOSING_CHANNEL: - if (pmt_eq(event, s_response_deallocate_channel)){ - status = pmt_nth(1, data); - - if (pmt_eq(status, PMT_T)){ - close_usrp(); - return; - } - else { - error_msg = "failed to deallocate channel:"; - goto bail; - } - } - goto unhandled; - - case CLOSING_USRP: - if (pmt_eq(event, s_response_close)){ - status = pmt_nth(1, data); - - if (pmt_eq(status, PMT_T)){ - shutdown_all(PMT_T); - return; - } - else { - error_msg = "failed to close USRP:"; - goto bail; - } - } - goto unhandled; - - default: - goto unhandled; - } - return; - - bail: - std::cerr << error_msg << data - << "status = " << status << std::endl; - shutdown_all(PMT_F); - return; - - unhandled: - if(verbose && 0) - std::cout << "test_usrp_inband_tx: unhandled msg: " << msg - << "in state "<< d_state << std::endl; -} - - -void -test_usrp_inband_timestamps::open_usrp() -{ - pmt_t which_usrp = pmt_from_long(0); - - d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, which_usrp)); - d_state = OPENING_USRP; -} - -void -test_usrp_inband_timestamps::close_usrp() -{ - d_cs->send(s_cmd_close, pmt_list1(PMT_NIL)); - d_state = CLOSING_USRP; - - if(verbose) - std::cout << "[TEST_USRP_INBAND_TIMESTAMPS] Closing USRP\n"; -} - -void -test_usrp_inband_timestamps::allocate_channel() -{ - long capacity = (long) 16e6; - d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity))); - d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity))); - d_state = ALLOCATING_CHANNEL; -} - -void -test_usrp_inband_timestamps::enter_receiving() -{ - d_rx->send(s_cmd_start_recv_raw_samples, - pmt_list2(PMT_F, - d_rx_chan)); -} - -void -test_usrp_inband_timestamps::enter_transmitting() -{ - d_state = TRANSMITTING; - d_nsamples_xmitted = 0; - - if(verbose) - std::cout << "[TEST_USRP_INBAND_TIMESTAMPS] Beginning transmission\n"; - - sleep(1); - - build_and_send_next_frame(); - build_and_send_next_frame(); - build_and_send_next_frame(); - build_and_send_next_frame(); - -} - -void -test_usrp_inband_timestamps::build_and_send_ping() -{ - - d_tx->send(s_cmd_to_control_channel, - pmt_list2(PMT_NIL, pmt_list1(pmt_list2(s_op_ping_fixed, - pmt_list2(pmt_from_long(0), - pmt_from_long(0)))))); - if(verbose && 0) - std::cout << "[TEST_USRP_INBAND_TIMESTAMPS] Ping sent" << std::endl; -} - -void -test_usrp_inband_timestamps::build_and_send_next_frame() -{ - // allocate the uniform vector for the samples - // FIXME perhaps hold on to this between calls - -#if 0 - long nsamples_this_frame = - std::min(d_nsamples_to_send - d_nsamples_xmitted, - d_samples_per_frame); -#else - long nsamples_this_frame = d_samples_per_frame; -#endif - - 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_writable_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; - - if(bskip) { - timestamp = pmt_from_long(0x0); // throw away - bcurr++; - if(bcurr == bstep) { - bskip = false; - bcurr = 0; - } - } else { - timestamp = pmt_from_long(0xffffffff); // NOW - timestamp = pmt_from_long(ptime); - ptime += incr; - bcurr++; - if(bcurr == bstep) { - //bskip = true; - bcurr = 0; - } - } - - std::cout << bskip << " -- " << bcurr << std::endl; - - 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_TIMESTAMPS] Transmitted frame\n"; - - //build_and_send_next_frame(); -} - - -void -test_usrp_inband_timestamps::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 - enter_closing_channel(); - } - - build_and_send_next_frame(); - //build_and_send_ping(); -} - -void -test_usrp_inband_timestamps::enter_closing_channel() -{ - d_state = CLOSING_CHANNEL; - - d_tx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_tx_chan)); - - if(verbose) - std::cout << "[TEST_USRP_INBAND_TIMESTAMPS] Closing channel\n"; -} - -REGISTER_MBLOCK_CLASS(test_usrp_inband_timestamps); - - -// ---------------------------------------------------------------- - -int -main (int argc, char **argv) -{ - // handle any command line args here - - mb_runtime_sptr rt = mb_make_runtime(); - pmt_t result = PMT_NIL; - - rt->run("top", "test_usrp_inband_timestamps", PMT_F, &result); -} diff --git a/usrp/limbo/apps-inband/test_usrp_inband_tx.cc b/usrp/limbo/apps-inband/test_usrp_inband_tx.cc deleted file mode 100644 index 9f294e770..000000000 --- a/usrp/limbo/apps-inband/test_usrp_inband_tx.cc +++ /dev/null @@ -1,411 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <mblock/mblock.h> -#include <mblock/runtime.h> -#include <mblock/protocol_class.h> -#include <mblock/exception.h> -#include <mblock/msg_queue.h> -#include <mblock/message.h> -#include <mblock/msg_accepter.h> -#include <mblock/class_registry.h> -#include <pmt.h> -#include <stdio.h> -#include <string.h> -#include <iostream> - -#include <ui_nco.h> -#include <symbols_usrp_server_cs.h> -#include <symbols_usrp_channel.h> -#include <symbols_usrp_low_level_cs.h> -#include <symbols_usrp_tx.h> - -static bool verbose = true; - -class test_usrp_tx : public mb_mblock -{ - mb_port_sptr d_tx; - mb_port_sptr d_cs; - pmt_t d_tx_chan; // returned tx channel handle - - enum state_t { - INIT, - OPENING_USRP, - ALLOCATING_CHANNEL, - TRANSMITTING, - CLOSING_CHANNEL, - 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; - - public: - test_usrp_tx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg); - ~test_usrp_tx(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - protected: - void open_usrp(); - void close_usrp(); - void allocate_channel(); - void send_packets(); - void enter_transmitting(); - void build_and_send_next_frame(); - void handle_xmit_response(pmt_t invocation_handle); - void enter_closing_channel(); -}; - -test_usrp_tx::test_usrp_tx(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(runtime, instance_name, user_arg), - d_state(INIT), d_nsamples_to_send((long) 80e6), - d_nsamples_xmitted(0), - d_nframes_xmitted(0), - d_samples_per_frame((long)(126 * 4)), // full packet - d_done_sending(false), - d_amplitude(16384) -{ - // std::cout << "[TEST_USRP_TX] Initializing...\n"; - - d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL); - d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL); - - //bool fake_usrp_p = true; - bool fake_usrp_p = false; - - // Test the TX side - - pmt_t usrp_dict = pmt_make_dict(); - - if(fake_usrp_p) { - pmt_dict_set(usrp_dict, - pmt_intern("fake-usrp"), - PMT_T); - } - - // Specify the RBF to use - pmt_dict_set(usrp_dict, - pmt_intern("rbf"), - pmt_intern("inband_1rxhb_1tx.rbf")); - - // Set TX and RX interpolations - pmt_dict_set(usrp_dict, - pmt_intern("interp-tx"), - pmt_from_long(64)); - -// If unspecified, chooses center frequency from range -// pmt_dict_set(usrp_dict, -// pmt_intern("rf-freq"), -// pmt_from_long(10e6)); - - define_component("server", "usrp_server", usrp_dict); - - connect("self", "tx0", "server", "tx0"); - 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); - - // FIXME need to somehow set the interp rate in the USRP. - // for now, we'll have the low-level code hardwire it. -} - -test_usrp_tx::~test_usrp_tx() -{ -} - -void -test_usrp_tx::initial_transition() -{ - open_usrp(); -} - -void -test_usrp_tx::handle_message(mb_message_sptr msg) -{ - pmt_t event = msg->signal(); - pmt_t data = msg->data(); - - pmt_t handle = PMT_F; - pmt_t status = PMT_F; - std::string error_msg; - - //std::cout << msg << std::endl; - - switch(d_state){ - case OPENING_USRP: - if (pmt_eq(event, s_response_open)){ - status = pmt_nth(1, data); - if (pmt_eq(status, PMT_T)){ - allocate_channel(); - return; - } - else { - error_msg = "failed to open usrp:"; - goto bail; - } - } - goto unhandled; - - case ALLOCATING_CHANNEL: - if (pmt_eq(event, s_response_allocate_channel)){ - status = pmt_nth(1, data); - d_tx_chan = pmt_nth(2, data); - - if (pmt_eq(status, PMT_T)){ - enter_transmitting(); - return; - } - else { - error_msg = "failed to allocate channel:"; - goto bail; - } - } - goto unhandled; - - case TRANSMITTING: - 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; - } - } - goto unhandled; - - case CLOSING_CHANNEL: - if (pmt_eq(event, s_response_deallocate_channel)){ - status = pmt_nth(1, data); - - if (pmt_eq(status, PMT_T)){ - close_usrp(); - return; - } - else { - error_msg = "failed to deallocate channel:"; - goto bail; - } - } - goto unhandled; - - case CLOSING_USRP: - if (pmt_eq(event, s_response_close)){ - status = pmt_nth(1, data); - - if (pmt_eq(status, PMT_T)){ - shutdown_all(PMT_T); - return; - } - else { - error_msg = "failed to close USRP:"; - goto bail; - } - } - goto unhandled; - - default: - goto unhandled; - } - return; - - bail: - std::cerr << error_msg << data - << "status = " << status << std::endl; - shutdown_all(PMT_F); - return; - - unhandled: - std::cout << "test_usrp_inband_tx: unhandled msg: " << msg - << "in state "<< d_state << std::endl; -} - - -void -test_usrp_tx::open_usrp() -{ - pmt_t which_usrp = pmt_from_long(0); - - d_cs->send(s_cmd_open, pmt_list2(PMT_NIL, which_usrp)); - d_state = OPENING_USRP; - - if(verbose) - std::cout << "[TEST_USRP_INBAND_TX] Opening the USRP\n"; -} - -void -test_usrp_tx::close_usrp() -{ - d_cs->send(s_cmd_close, pmt_list1(PMT_NIL)); - d_state = CLOSING_USRP; - - if(verbose) - std::cout << "[TEST_USRP_INBAND_TX] Closing the USRP\n"; -} - -void -test_usrp_tx::allocate_channel() -{ - long capacity = (long) 16e6; - d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity))); - d_state = ALLOCATING_CHANNEL; - - if(verbose) - std::cout << "[TEST_USRP_INBAND_TX] Requesting TX channel allocation\n"; -} - -void -test_usrp_tx::enter_transmitting() -{ - d_state = TRANSMITTING; - d_nsamples_xmitted = 0; - - if(verbose) - std::cout << "[TEST_USRP_INBAND_TX] Transmitting...\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_tx::build_and_send_next_frame() -{ - // allocate the uniform vector for the samples - // FIXME perhaps hold on to this between calls - -#if 1 - long nsamples_this_frame = - std::min(d_nsamples_to_send - d_nsamples_xmitted, - d_samples_per_frame); -#else - long nsamples_this_frame = d_samples_per_frame; -#endif - - 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_writable_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 tx_properties = pmt_make_dict(); - - pmt_t timestamp = pmt_from_long(0xffffffff); // NOW - d_tx->send(s_cmd_xmit_raw_frame, - pmt_list5(pmt_from_long(d_nframes_xmitted), // invocation-handle - d_tx_chan, // channel - uvec, // the samples - timestamp, - tx_properties)); - - d_nsamples_xmitted += nsamples_this_frame; - d_nframes_xmitted++; - - if(verbose && 0) - std::cout << "[TEST_USRP_INBAND_TX] Transmitted frame\n"; -} - - -void -test_usrp_tx::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 - enter_closing_channel(); - } - - build_and_send_next_frame(); -} - -void -test_usrp_tx::enter_closing_channel() -{ - d_state = CLOSING_CHANNEL; - - d_tx->send(s_cmd_deallocate_channel, pmt_list2(PMT_NIL, d_tx_chan)); - - if(verbose) - std::cout << "[TEST_USRP_INBAND_tX] Deallocating TX channel\n"; -} - -REGISTER_MBLOCK_CLASS(test_usrp_tx); - - -// ---------------------------------------------------------------- - -int -main (int argc, char **argv) -{ - // handle any command line args here - - mb_runtime_sptr rt = mb_make_runtime(); - pmt_t result = PMT_NIL; - - rt->run("top", "test_usrp_tx", PMT_F, &result); -} diff --git a/usrp/limbo/apps-inband/test_usrp_inband_underrun.cc b/usrp/limbo/apps-inband/test_usrp_inband_underrun.cc deleted file mode 100644 index 11babb048..000000000 --- a/usrp/limbo/apps-inband/test_usrp_inband_underrun.cc +++ /dev/null @@ -1,674 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <mblock/mblock.h> -#include <mblock/runtime.h> -#include <mblock/protocol_class.h> -#include <mblock/exception.h> -#include <mblock/msg_queue.h> -#include <mblock/message.h> -#include <mblock/msg_accepter.h> -#include <mblock/class_registry.h> -#include <pmt.h> -#include <stdio.h> -#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> -#include <symbols_usrp_channel.h> -#include <symbols_usrp_low_level_cs.h> -#include <symbols_usrp_tx.h> -#include <symbols_usrp_rx.h> - -static bool verbose = true; - -class test_usrp_inband_underrun : public mb_mblock -{ - - mb_port_sptr d_tx; // Ports connected to the USRP server - mb_port_sptr d_rx; - mb_port_sptr d_cs; - - pmt_t d_tx_chan; // Returned channel from TX allocation - pmt_t d_rx_chan; // Returned channel from RX allocation - - pmt_t d_which_usrp; // The USRP to use for the test - - long d_warm_msgs; // The number of messages to 'warm' the USRP - long d_warm_recvd; // The number of msgs received in the 'warm' state - - // Keep track of current state - enum state_t { - INIT, - OPENING_USRP, - 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(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - protected: - void opening_usrp(); - void allocating_channels(); - void write_register(); - void read_register(); - 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); -}; - - -int -main (int argc, char **argv) -{ - // handle any command line args here - - mb_runtime_sptr rt = mb_make_runtime(); - pmt_t result = PMT_NIL; - - rt->run("top", "test_usrp_inband_underrun", PMT_F, &result); -} - - -test_usrp_inband_underrun::test_usrp_inband_underrun(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(runtime, instance_name, user_arg), - d_tx_chan(PMT_NIL), - d_rx_chan(PMT_NIL), - d_which_usrp(pmt_from_long(0)), - d_state(INIT), - d_nsamples_to_send((long) 27e6), - 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 - pmt_t usrp_dict = pmt_make_dict(); - - // Specify the RBF to use - pmt_dict_set(usrp_dict, - pmt_intern("rbf"), - pmt_intern("inband_1rxhb_1tx.rbf")); - - // Set TX and RX interpolations - pmt_dict_set(usrp_dict, - pmt_intern("interp-tx"), - pmt_from_long(64)); - - pmt_dict_set(usrp_dict, - pmt_intern("decim-rx"), - pmt_from_long(128)); - - d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL); - d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL); - d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL); - - // Create an instance of USRP server and connect ports - define_component("server", "usrp_server", usrp_dict); - connect("self", "tx0", "server", "tx0"); - 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() -{ -} - -void -test_usrp_inband_underrun::initial_transition() -{ - opening_usrp(); -} - -// Handle message reads all incoming messages from USRP server which will be -// initialization and ping responses. We perform actions based on the current -// state and the event (ie, ping response) -void -test_usrp_inband_underrun::handle_message(mb_message_sptr msg) -{ - pmt_t event = msg->signal(); - pmt_t data = msg->data(); - pmt_t port_id = msg->port_id(); - - pmt_t handle = PMT_F; - pmt_t status = PMT_F; - pmt_t dict = PMT_NIL; - std::string error_msg; - - // 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; - } - } - - - // Dispatch based on state - switch(d_state) { - - //----------------------------- OPENING_USRP ----------------------------// - // We only expect a response from opening the USRP which should be succesful - // or failed. - case OPENING_USRP: - - if(pmt_eq(event, s_response_open)) { - - status = pmt_nth(1, data); // failed/succes - - if(pmt_eq(status, PMT_T)) { - allocating_channels(); - return; - } - else { - error_msg = "failed to open usrp:"; - goto bail; - } - - } - - goto unhandled; // all other messages not handled in this state - - - //----------------------- ALLOCATING CHANNELS --------------------// - // When allocating channels, we need to wait for 2 responses from - // USRP server: one for TX and one for RX. Both are initialized to - // NIL so we know to continue to the next state once both are set. - case ALLOCATING_CHANNELS: - - // A TX allocation response - if(pmt_eq(event, s_response_allocate_channel) - && pmt_eq(d_tx->port_symbol(), port_id)) - { - status = pmt_nth(1, data); - - // If successful response, extract the channel - if(pmt_eq(status, PMT_T)) { - - d_tx_chan = pmt_nth(2, data); - - if(verbose) - 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(); - enter_transmitting(); - } - - return; - } - else { // TX allocation failed - error_msg = "failed to allocate TX channel:"; - goto bail; - } - } - - // A RX allocation response - if(pmt_eq(event, s_response_allocate_channel) - && pmt_eq(d_rx->port_symbol(), port_id)) - { - status = pmt_nth(1, data); - - // If successful response, extract the channel - if(pmt_eq(status, PMT_T)) { - - d_rx_chan = pmt_nth(2, data); - - if(verbose) - 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(); - enter_transmitting(); - } - - return; - } - else { // RX allocation failed - error_msg = "failed to allocate RX channel:"; - goto bail; - } - } - - goto unhandled; - - case WRITE_REGISTER: - goto unhandled; - - case READ_REGISTER: - goto unhandled; - - //-------------------------- 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; - } - } - - 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 successful, set the port to NIL - if(pmt_eq(status, PMT_T)) { - d_tx_chan = PMT_NIL; - - if(verbose) - std::cout << "[TEST_USRP_INBAND_UNDERRUN] Received TX deallocation\n"; - - // If the RX is also deallocated, we can close the USRP - if(pmt_eq(d_rx_chan, PMT_NIL)) - closing_usrp(); - - 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_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 { - - error_msg = "failed to deallocate RX channel:"; - goto bail; - - } - } - - 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; - fflush(stdout); - - shutdown_all(PMT_T); - return; - - } else { - - error_msg = "failed to close USRP:"; - goto bail; - } - } - - goto unhandled; - - case INIT: - goto unhandled; - - } - - // An error occured, print it, and shutdown all m-blocks - bail: - std::cerr << error_msg << data - << "status = " << status << std::endl; - shutdown_all(PMT_F); - return; - - // Received an unhandled message for a specific state - unhandled: - if(verbose && !pmt_eq(event, pmt_intern("%shutdown"))) - std::cout << "test_usrp_inband_tx: unhandled msg: " << msg - << "in state "<< d_state << std::endl; - -} - - -// Sends a command to USRP server to open up a connection to the -// specified USRP, which is defaulted to USRP 0 on the system -void -test_usrp_inband_underrun::opening_usrp() -{ - - if(verbose) - 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)); - d_state = OPENING_USRP; -} - -// RX and TX channels must be allocated so that the USRP server can -// properly share bandwidth across multiple USRPs. No commands will be -// successful to the USRP through the USRP server on the TX or RX channels until -// a bandwidth allocation has been received. -void -test_usrp_inband_underrun::allocating_channels() -{ - d_state = ALLOCATING_CHANNELS; - - long capacity = (long) 16e6; - d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity))); - d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(capacity))); -} - -// After allocating the channels, a write register command will be sent to the -// USRP. -void -test_usrp_inband_underrun::write_register() -{ - d_state = WRITE_REGISTER; - - long reg = 0; - - d_tx->send(s_cmd_to_control_channel, // C/S packet - pmt_list2(PMT_NIL, // invoc handle - pmt_list1( - pmt_list2(s_op_write_reg, - pmt_list2( - pmt_from_long(reg), - pmt_from_long(0xbeef)))))); - - if(verbose) - std::cout << "[TEST_USRP_INBAND_REGISTERS] Writing 0xbeef to " - << reg << std::endl; - - read_register(); // immediately transition to read the register -} - -// Temporary: for testing pings -void -test_usrp_inband_underrun::build_and_send_ping() -{ - - d_tx->send(s_cmd_to_control_channel, - pmt_list2(PMT_NIL, pmt_list1(pmt_list2(s_op_ping_fixed, - pmt_list2(pmt_from_long(0), - pmt_from_long(0)))))); - - 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 -// it is the same value that we wrote. -void -test_usrp_inband_underrun::read_register() -{ - d_state = READ_REGISTER; - - long reg = 9; - - d_tx->send(s_cmd_to_control_channel, // C/S packet - pmt_list2(PMT_NIL, // invoc handle - pmt_list1( - pmt_list2(s_op_read_reg, - pmt_list2( - pmt_from_long(0), // rid - pmt_from_long(reg)))))); - if(verbose) - std::cout << "[TEST_USRP_INBAND_UNDERRUN] Reading from register " - << reg << std::endl; -} - -// Used to enter the receiving state -void -test_usrp_inband_underrun::enter_receiving() -{ - d_rx->send(s_cmd_start_recv_raw_samples, - pmt_list2(PMT_F, - d_rx_chan)); - - if(verbose) - std::cout << "[TEST_USRP_INBAND_UNDERRUN] Started RX sample stream\n"; -} - -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_writable_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(); - } - } - - if(verbose) - std::cout << "[TEST_USRP_INBAND_TX] Transmitting frame...\n"; - - 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) - 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(); - return; - } - - 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++; - - if(verbose && 0) - std::cout << "[TEST_USRP_INBAND_UNDERRUN] Underrun\n"; - } - else { - if(verbose && 0) - std::cout << "[TEST_USRP_INBAND_UNDERRUN] No underrun\n" << underrun <<std::endl; - } - } else { - - if(verbose && 0) - std::cout << "[TEST_USRP_INBAND_UNDERRUN] No underrun\n"; - } - -} - -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); diff --git a/usrp/limbo/apps-inband/ui_nco.h b/usrp/limbo/apps-inband/ui_nco.h deleted file mode 100644 index e6d7814ab..000000000 --- a/usrp/limbo/apps-inband/ui_nco.h +++ /dev/null @@ -1,202 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2002 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ -#ifndef INCLUDED_UI_NCO_H -#define INCLUDED_UI_NCO_H - - -#include <vector> -#include <ui_sincos.h> -#include <cmath> - -#include <complex> -typedef std::complex<float> gr_complex; - - -/*! - * \brief base class template for Numerically Controlled Oscillator (NCO) - */ - - -//FIXME Eventually generalize this to fixed point - -template<class o_type, class i_type> -class ui_nco { -public: - ui_nco () : phase (0), phase_inc(0) {} - - virtual ~ui_nco () {} - - // radians - void set_phase (double angle) { - phase = angle; - } - - void adjust_phase (double delta_phase) { - phase += delta_phase; - } - - - // angle_rate is in radians / step - void set_freq (double angle_rate){ - phase_inc = angle_rate; - } - - // angle_rate is a delta in radians / step - void adjust_freq (double delta_angle_rate) - { - phase_inc += delta_angle_rate; - } - - // increment current phase angle - - void step () - { - phase += phase_inc; - if (fabs (phase) > M_PI){ - - while (phase > M_PI) - phase -= 2*M_PI; - - while (phase < -M_PI) - phase += 2*M_PI; - } - } - - void step (int n) - { - phase += phase_inc * n; - if (fabs (phase) > M_PI){ - - while (phase > M_PI) - phase -= 2*M_PI; - - while (phase < -M_PI) - phase += 2*M_PI; - } - } - - // units are radians / step - double get_phase () const { return phase; } - double get_freq () const { return phase_inc; } - - // compute sin and cos for current phase angle - void sincos (float *sinx, float *cosx) const; - - // compute cos or sin for current phase angle - float cos () const { return std::cos (phase); } - float sin () const { return std::sin (phase); } - - // compute a block at a time - void sin (float *output, int noutput_items, double ampl = 1.0); - void cos (float *output, int noutput_items, double ampl = 1.0); - void sincos (gr_complex *output, int noutput_items, double ampl = 1.0); - void sin (short *output, int noutput_items, double ampl = 1.0); - void cos (short *output, int noutput_items, double ampl = 1.0); - void sin (int *output, int noutput_items, double ampl = 1.0); - void cos (int *output, int noutput_items, double ampl = 1.0); - -protected: - double phase; - double phase_inc; -}; - -template<class o_type, class i_type> -void -ui_nco<o_type,i_type>::sincos (float *sinx, float *cosx) const -{ - ui_sincosf (phase, sinx, cosx); -} - -template<class o_type, class i_type> -void -ui_nco<o_type,i_type>::sin (float *output, int noutput_items, double ampl) -{ - for (int i = 0; i < noutput_items; i++){ - output[i] = (float)(sin () * ampl); - step (); - } -} - -template<class o_type, class i_type> -void -ui_nco<o_type,i_type>::cos (float *output, int noutput_items, double ampl) -{ - for (int i = 0; i < noutput_items; i++){ - output[i] = (float)(cos () * ampl); - step (); - } -} - -template<class o_type, class i_type> -void -ui_nco<o_type,i_type>::sin (short *output, int noutput_items, double ampl) -{ - for (int i = 0; i < noutput_items; i++){ - output[i] = (short)(sin() * ampl); - step (); - } -} - -template<class o_type, class i_type> -void -ui_nco<o_type,i_type>::cos (short *output, int noutput_items, double ampl) -{ - for (int i = 0; i < noutput_items; i++){ - output[i] = (short)(cos () * ampl); - step (); - } -} - -template<class o_type, class i_type> -void -ui_nco<o_type,i_type>::sin (int *output, int noutput_items, double ampl) -{ - for (int i = 0; i < noutput_items; i++){ - output[i] = (int)(sin () * ampl); - step (); - } -} - -template<class o_type, class i_type> -void -ui_nco<o_type,i_type>::cos (int *output, int noutput_items, double ampl) -{ - for (int i = 0; i < noutput_items; i++){ - output[i] = (int)(cos () * ampl); - step (); - } -} - -template<class o_type, class i_type> -void -ui_nco<o_type,i_type>::sincos (gr_complex *output, int noutput_items, double ampl) -{ - for (int i = 0; i < noutput_items; i++){ - float cosx, sinx; - sincos (&sinx, &cosx); - output[i] = gr_complex(cosx * ampl, sinx * ampl); - step (); - } -} - -#endif /* INCLUDED_UI_NCO_H */ - diff --git a/usrp/limbo/apps-inband/ui_sincos.c b/usrp/limbo/apps-inband/ui_sincos.c deleted file mode 100644 index 27841f010..000000000 --- a/usrp/limbo/apps-inband/ui_sincos.c +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#define _GNU_SOURCE // ask for GNU extensions if available - -#include "ui_sincos.h" -#include <math.h> - -// ---------------------------------------------------------------- - -#if defined (HAVE_SINCOS) - -void -ui_sincos (double x, double *sinx, double *cosx) -{ - sincos (x, sinx, cosx); -} - -#else - -void -ui_sincos (double x, double *sinx, double *cosx) -{ - *sinx = sin (x); - *cosx = cos (x); -} - -#endif - -// ---------------------------------------------------------------- - -#if defined (HAVE_SINCOSF) - -void -ui_sincosf (float x, float *sinx, float *cosx) -{ - sincosf (x, sinx, cosx); -} - -#elif defined (HAVE_SINF) && defined (HAVE_COSF) - -void -ui_sincosf (float x, float *sinx, float *cosx) -{ - *sinx = sinf (x); - *cosx = cosf (x); -} - -#else - -void -ui_sincosf (float x, float *sinx, float *cosx) -{ - *sinx = sin (x); - *cosx = cos (x); -} - -#endif diff --git a/usrp/limbo/apps-inband/ui_sincos.h b/usrp/limbo/apps-inband/ui_sincos.h deleted file mode 100644 index d2d6e4b76..000000000 --- a/usrp/limbo/apps-inband/ui_sincos.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2002,2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_UI_SINCOS_H -#define INCLUDED_UI_SINCOS_H - -#ifdef __cplusplus -extern "C" { -#endif - -// compute sine and cosine at the same time - -void ui_sincos (double x, double *sin, double *cos); -void ui_sincosf (float x, float *sin, float *cos); - -#ifdef __cplusplus -}; -#endif - -#endif /* INCLUDED_UI_SINCOS_H */ diff --git a/usrp/limbo/inband/.gitignore b/usrp/limbo/inband/.gitignore deleted file mode 100644 index a228dcdc1..000000000 --- a/usrp/limbo/inband/.gitignore +++ /dev/null @@ -1,20 +0,0 @@ -/Makefile -/Makefile.in -/.la -/.lo -/.deps -/.libs -/*.la -/*.lo -/*.swp -/*.dat -/test_fusb -/std_paths.h -/usrp_dbid.py -/usrp_dbid.h -/usrp_dbid.cc -/usrp_server_mbh.cc -/test_inband -/test_usrp_inband -/test_usrp_tx -/*_mbh.cc diff --git a/usrp/limbo/inband/Makefile.am b/usrp/limbo/inband/Makefile.am deleted file mode 100644 index 650a25ff9..000000000 --- a/usrp/limbo/inband/Makefile.am +++ /dev/null @@ -1,114 +0,0 @@ -# -# Copyright 2007,2008 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# - -include $(top_srcdir)/Makefile.common - -AM_CPPFLAGS = \ - $(DEFINES) $(OMNITHREAD_INCLUDES) $(PMT_INCLUDES) $(MBLOCK_INCLUDES) \ - $(USRP_INCLUDES) $(BOOST_CPPFLAGS) $(CPPUNIT_INCLUDES) \ - -I$(srcdir)/../../apps-inband $(WITH_INCLUDES) - -TESTS = test_inband - -EXTRA_DIST = \ - usrp_server.mbh \ - usrp_interface.mbh - -lib_LTLIBRARIES = \ - libusrp-inband.la \ - libusrp-inband-qa.la - -# ------------------------------------------------------------------------ -# Build the inband library - -BUILT_SOURCES = \ - usrp_server_mbh.cc \ - usrp_interface_mbh.cc - -usrp_server_mbh.cc : usrp_server.mbh - $(COMPILE_MBH) $(srcdir)/usrp_server.mbh usrp_server_mbh.cc - -usrp_interface_mbh.cc : usrp_interface.mbh - $(COMPILE_MBH) $(srcdir)/usrp_interface.mbh usrp_interface_mbh.cc - -libusrp_inband_la_SOURCES = \ - $(BUILT_SOURCES) \ - $(srcdir)/../../apps-inband/ui_sincos.c \ - usrp_inband_usb_packet.cc \ - usrp_rx.cc \ - usrp_rx_stub.cc \ - usrp_server.cc \ - usrp_tx.cc \ - usrp_tx_stub.cc \ - usrp_usb_interface.cc - -libusrp_inband_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0 - -libusrp_inband_la_LIBADD = \ - $(MBLOCK_LA) \ - $(USRP_LA) \ - -lstdc++ - -include_HEADERS = \ - usrp_inband_usb_packet.h \ - usrp_rx.h \ - usrp_rx_stub.h \ - usrp_server.h \ - usrp_tx.h \ - usrp_tx_stub.h \ - usrp_usb_interface.h - -noinst_HEADERS = \ - qa_inband.h \ - qa_inband_packet_prims.h \ - qa_inband_usrp_server.h \ - symbols_usrp_channel.h \ - symbols_usrp_interface_cs.h \ - symbols_usrp_low_level_cs.h \ - symbols_usrp_rx.h \ - symbols_usrp_rx_cs.h \ - symbols_usrp_server_cs.h \ - symbols_usrp_tx.h \ - symbols_usrp_tx_cs.h - -# ------------------------------------------------------------------------ -# Build the qa code in its own library - -libusrp_inband_qa_la_SOURCES = \ - qa_inband.cc \ - qa_inband_packet_prims.cc \ - qa_inband_usrp_server.cc - -# magic flags -libusrp_inband_qa_la_LDFLAGS = $(NO_UNDEFINED) -avoid-version - -libusrp_inband_qa_la_LIBADD = \ - libusrp-inband.la \ - $(PMT_LA) \ - $(CPPUNIT_LIBS) \ - -lstdc++ - -# ------------------------------------------------------------------------ - -noinst_PROGRAMS = \ - test_inband - -test_inband_SOURCES = test_inband.cc -test_inband_LDADD = libusrp-inband-qa.la diff --git a/usrp/limbo/inband/dump_packets.py b/usrp/limbo/inband/dump_packets.py deleted file mode 100755 index 237362406..000000000 --- a/usrp/limbo/inband/dump_packets.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2007 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# - -import sys -import struct -from optparse import OptionParser - -from usb_packet import * - -def dump_packet(raw_pkt, outfile, dump_payload): - pkt = usb_packet(raw_pkt) - outfile.write(pkt.decoded_flags()) - outfile.write(' chan= %2d len= %3d timestamp= 0x%08x rssi= % 2d tag= %2d\n' % ( - pkt.chan(), pkt.payload_len(), pkt.timestamp(), pkt.rssi(), pkt.tag())) - if dump_payload: - assert pkt.payload_len() % 4 == 0 - shorts = struct.unpack('<%dh' % (pkt.payload_len() // 2), pkt.payload()) - for i in range(0, len(shorts), 2): - outfile.write(' %6d, %6d\n' % (shorts[i], shorts[i+1])) - - -def dump_packets(infile, outfile, dump_payload): - raw_pkt = infile.read(512) - while raw_pkt: - if len(raw_pkt) != 512: - sys.stderr.write("File length is not a multiple of 512 bytes") - raise SystemExit, 1 - - dump_packet(raw_pkt, outfile, dump_payload) - raw_pkt = infile.read(512) - - -def main(): - parser = OptionParser() - parser.add_option('-p', '--dump-payload', action='store_true', default=False, - help='dump payload in decimal and hex') - - (options, files) = parser.parse_args() - if len(files) == 0: - dump_packets(sys.stdin, sys.stdout, options.dump_payload) - else: - for f in files: - dump_packets(open(f, "r"), sys.stdout, options.dump_payload) - - -if __name__ == '__main__': - main() diff --git a/usrp/limbo/inband/gen_test_packets.py b/usrp/limbo/inband/gen_test_packets.py deleted file mode 100755 index 2ee646384..000000000 --- a/usrp/limbo/inband/gen_test_packets.py +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env python - -import random -import struct -from pprint import pprint -from usb_packet import * - -MAX_PAYLOAD = 504 -TIME_NOW = 0xffffffff - - -class sequence_generator(object): - def __init__(self): - self.i = 0 - - def __call__(self): - t = self.i - self.i += 1 - return t - -def gen_shuffled_lengths(): - valid_lengths = range(0, MAX_PAYLOAD+1, 4) # [0, 4, 8, ... 504] - random.shuffle(valid_lengths) - return valid_lengths - - -class packet_sequence_generator(object): - def __init__(self, channel, lengths): - self.next = sequence_generator() - self.channel = channel - self.lengths = lengths - - def __call__(self, output_file): - gen_packet(output_file, self.channel, self.next, self.lengths[0]) - del self.lengths[0] - - -def gen_packet(output_file, channel, content_generator, payload_len): - assert (payload_len % 4) == 0 - payload = [] - n_iq = payload_len // 4 - for n in range(n_iq): - payload.append(content_generator()) # I - payload.append(content_generator()) # Q - for n in range(MAX_PAYLOAD // 4 - n_iq): - payload.append(0x0000) - payload.append(0xffff) - - assert (len(payload) == MAX_PAYLOAD // 2) - - #print "\npayload_len =", payload_len - #pprint(payload) - - output_file.write(make_header(FL_START_OF_BURST|FL_END_OF_BURST, - channel, payload_len, TIME_NOW)) - output_file.write(struct.pack('<252h', *payload)) - - -def gen_all_valid_packet_lengths_1_channel(output_file): - lengths = gen_shuffled_lengths() - npkts = len(lengths) # number of packets we'll generator on each stream - pkt_gen_0 = packet_sequence_generator(0, lengths) - for i in range(npkts): - pkt_gen_0(output_file) - - assert pkt_gen_0.next() == 16002 # 2*sum(1, 2, ..., 126) == 126 * 127 - - -def gen_all_valid_packet_lengths_2_channels(output_file): - lengths = gen_shuffled_lengths() - npkts = len(lengths) # number of packets we'll generator on each stream - pkt_gen_0 = packet_sequence_generator(0, lengths) - pkt_gen_1 = packet_sequence_generator(0x1f, gen_shuffled_lengths()) - pkt_gen = (pkt_gen_0, pkt_gen_1) - - which_gen = (npkts * [0]) + (npkts * [1]) - random.shuffle(which_gen) - - for i in which_gen: - pkt_gen[i](output_file) - - assert pkt_gen_0.next() == 16002 # 2*sum(1, 2, ..., 126) == 126 * 127 - assert pkt_gen_1.next() == 16002 # 2*sum(1, 2, ..., 126) == 126 * 127 - -if __name__ == '__main__': - random.seed(0) - gen_all_valid_packet_lengths_1_channel(open("all_valid_packet_lengths_1_channel.dat", "w")) - gen_all_valid_packet_lengths_2_channels(open("all_valid_packet_lengths_2_channels.dat", "w")) diff --git a/usrp/limbo/inband/qa_inband.cc b/usrp/limbo/inband/qa_inband.cc deleted file mode 100644 index 6f33a6ead..000000000 --- a/usrp/limbo/inband/qa_inband.cc +++ /dev/null @@ -1,35 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <qa_inband.h> -#include <qa_inband_packet_prims.h> -#include <qa_inband_usrp_server.h> - -CppUnit::TestSuite * -qa_inband::suite() -{ - CppUnit::TestSuite *s = new CppUnit::TestSuite("inband"); - - s->addTest (qa_inband_packet_prims::suite()); - s->addTest (qa_inband_usrp_server::suite()); - - return s; -} diff --git a/usrp/limbo/inband/qa_inband.h b/usrp/limbo/inband/qa_inband.h deleted file mode 100644 index ab8f7f250..000000000 --- a/usrp/limbo/inband/qa_inband.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef INCLUDED_QA_INBAND_H -#define INCLUDED_QA_INBAND_H - -#include <cppunit/TestSuite.h> - -//! collect all the tests for the user server - -class qa_inband { - public: - //! return suite of tests for all of usrp server - static CppUnit::TestSuite *suite(); -}; - -#endif /* INCLUDED_QA_INBAND_H */ diff --git a/usrp/limbo/inband/qa_inband_packet_prims.cc b/usrp/limbo/inband/qa_inband_packet_prims.cc deleted file mode 100644 index d9bbbec22..000000000 --- a/usrp/limbo/inband/qa_inband_packet_prims.cc +++ /dev/null @@ -1,162 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <qa_inband_packet_prims.h> -#include <cppunit/TestAssert.h> -#include <stdio.h> -#include <string.h> -#include <usrp_inband_usb_packet.h> // will change on gigabit crossover - -typedef usrp_inband_usb_packet transport_pkt; - -void -qa_inband_packet_prims::test_flags() -{ - transport_pkt pkt; - - // Test each one of the flags while ensuring no other fields become set in the process - pkt.set_header(pkt.FL_START_OF_BURST,0,0,0); - CPPUNIT_ASSERT_EQUAL(1, pkt.start_of_burst()); - CPPUNIT_ASSERT_EQUAL(0, pkt.end_of_burst()); - CPPUNIT_ASSERT_EQUAL(0, pkt.overrun()); - CPPUNIT_ASSERT_EQUAL(0, pkt.underrun()); - CPPUNIT_ASSERT_EQUAL(0, pkt.dropped()); - CPPUNIT_ASSERT_EQUAL(0, pkt.chan()); - CPPUNIT_ASSERT_EQUAL(0, pkt.tag()); - CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len()); - - pkt.set_header(pkt.FL_END_OF_BURST,0,0,0); - CPPUNIT_ASSERT_EQUAL(0, pkt.start_of_burst()); - CPPUNIT_ASSERT_EQUAL(1, pkt.end_of_burst()); - CPPUNIT_ASSERT_EQUAL(0, pkt.overrun()); - CPPUNIT_ASSERT_EQUAL(0, pkt.underrun()); - CPPUNIT_ASSERT_EQUAL(0, pkt.dropped()); - CPPUNIT_ASSERT_EQUAL(0, pkt.chan()); - CPPUNIT_ASSERT_EQUAL(0, pkt.tag()); - CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len()); - - pkt.set_header(pkt.FL_OVERRUN,0,0,0); - CPPUNIT_ASSERT_EQUAL(0, pkt.start_of_burst()); - CPPUNIT_ASSERT_EQUAL(0, pkt.end_of_burst()); - CPPUNIT_ASSERT_EQUAL(1, pkt.overrun()); - CPPUNIT_ASSERT_EQUAL(0, pkt.underrun()); - CPPUNIT_ASSERT_EQUAL(0, pkt.dropped()); - CPPUNIT_ASSERT_EQUAL(0, pkt.chan()); - CPPUNIT_ASSERT_EQUAL(0, pkt.tag()); - CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len()); - - pkt.set_header(pkt.FL_UNDERRUN,0,0,0); - CPPUNIT_ASSERT_EQUAL(0, pkt.start_of_burst()); - CPPUNIT_ASSERT_EQUAL(0, pkt.end_of_burst()); - CPPUNIT_ASSERT_EQUAL(0, pkt.overrun()); - CPPUNIT_ASSERT_EQUAL(1, pkt.underrun()); - CPPUNIT_ASSERT_EQUAL(0, pkt.dropped()); - CPPUNIT_ASSERT_EQUAL(0, pkt.chan()); - CPPUNIT_ASSERT_EQUAL(0, pkt.tag()); - CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len()); - - pkt.set_header(pkt.FL_DROPPED,0,0,0); - CPPUNIT_ASSERT_EQUAL(0, pkt.start_of_burst()); - CPPUNIT_ASSERT_EQUAL(0, pkt.end_of_burst()); - CPPUNIT_ASSERT_EQUAL(0, pkt.overrun()); - CPPUNIT_ASSERT_EQUAL(0, pkt.underrun()); - CPPUNIT_ASSERT_EQUAL(1, pkt.dropped()); - CPPUNIT_ASSERT_EQUAL(0, pkt.chan()); - CPPUNIT_ASSERT_EQUAL(0, pkt.tag()); - CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len()); - - // test of all fields set - pkt.set_header( - pkt.FL_START_OF_BURST | - pkt.FL_END_OF_BURST | - pkt.FL_UNDERRUN | - pkt.FL_OVERRUN | - pkt.FL_DROPPED - ,0,0,0); - CPPUNIT_ASSERT_EQUAL(1, pkt.start_of_burst()); - CPPUNIT_ASSERT_EQUAL(1, pkt.end_of_burst()); - CPPUNIT_ASSERT_EQUAL(1, pkt.overrun()); - CPPUNIT_ASSERT_EQUAL(1, pkt.underrun()); - CPPUNIT_ASSERT_EQUAL(1, pkt.dropped()); - CPPUNIT_ASSERT_EQUAL(0, pkt.chan()); - CPPUNIT_ASSERT_EQUAL(0, pkt.tag()); - CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len()); - - -} -////////////////////////////////////////////////////////////////////// - -void -qa_inband_packet_prims::test_fields() -{ - transport_pkt pkt; - void * payload; - - // test word0 field exclusiveness - // - // I want to test max values of each field to ensure field boundaries - // but these max values could change based on technology? The - // max payload is returned by a private method so the code is not - // technology dependent - pkt.set_header(0,16,0,0); - CPPUNIT_ASSERT_EQUAL(16, pkt.chan()); - CPPUNIT_ASSERT_EQUAL(0, pkt.tag()); - CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len()); - - pkt.set_header(0,0,8,0); - CPPUNIT_ASSERT_EQUAL(0, pkt.chan()); - CPPUNIT_ASSERT_EQUAL(8, pkt.tag()); - CPPUNIT_ASSERT_EQUAL(0,pkt.payload_len()); - - pkt.set_header(0,0,0,pkt.max_payload()); - CPPUNIT_ASSERT_EQUAL(0, pkt.chan()); - CPPUNIT_ASSERT_EQUAL(0, pkt.tag()); - CPPUNIT_ASSERT_EQUAL(pkt.max_payload(), pkt.payload_len()); - - // test timestamp, shouldn't have to test other fields since - // setting the timestamp only has the ability to affect one word - pkt.set_timestamp(54); - CPPUNIT_ASSERT_EQUAL(uint32_t(54), pkt.timestamp()); - - // test the payload, ensure no other fields overwritten - // - // is there a better test for this? - pkt.set_header(0,0,0,0); - payload = malloc(pkt.payload_len()); - memset(payload, 'f', pkt.payload_len()); - memcpy(pkt.payload(), payload, pkt.payload_len()); - CPPUNIT_ASSERT_EQUAL(0, memcmp(pkt.payload(), payload, pkt.payload_len())); - CPPUNIT_ASSERT_EQUAL(0, pkt.start_of_burst()); - CPPUNIT_ASSERT_EQUAL(0, pkt.end_of_burst()); - CPPUNIT_ASSERT_EQUAL(0, pkt.overrun()); - CPPUNIT_ASSERT_EQUAL(0, pkt.underrun()); - CPPUNIT_ASSERT_EQUAL(0, pkt.dropped()); - CPPUNIT_ASSERT_EQUAL(0, pkt.chan()); - CPPUNIT_ASSERT_EQUAL(0, pkt.tag()); - CPPUNIT_ASSERT_EQUAL(0, pkt.payload_len()); - free(payload); - -} -////////////////////////////////////////////////////////////////////// diff --git a/usrp/limbo/inband/qa_inband_packet_prims.h b/usrp/limbo/inband/qa_inband_packet_prims.h deleted file mode 100644 index 71c0d737d..000000000 --- a/usrp/limbo/inband/qa_inband_packet_prims.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef QA_INBAND_PACKET_PRIMS_H -#define QA_INBAND_PACKET_PRIMS_H - -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/TestCase.h> - -class qa_inband_packet_prims : public CppUnit::TestCase { - - CPPUNIT_TEST_SUITE(qa_inband_packet_prims); - CPPUNIT_TEST(test_flags); - CPPUNIT_TEST(test_fields); - CPPUNIT_TEST_SUITE_END(); - - private: - void test_flags(); - void test_fields(); - -}; - -#endif /* INCLUDED_QA_INBAND_PACKET_PRIMS_H */ diff --git a/usrp/limbo/inband/qa_inband_usrp_server.cc b/usrp/limbo/inband/qa_inband_usrp_server.cc deleted file mode 100644 index 6049a8a87..000000000 --- a/usrp/limbo/inband/qa_inband_usrp_server.cc +++ /dev/null @@ -1,1575 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <usrp_inband_usb_packet.h> -#include <qa_inband_usrp_server.h> -#include <cppunit/TestAssert.h> -#include <stdio.h> -#include <usrp_server.h> -#include <mblock/mblock.h> -#include <mblock/runtime.h> -#include <mblock/protocol_class.h> -#include <mblock/class_registry.h> -#include <vector> -#include <iostream> -#include <pmt.h> - -#include <symbols_usrp_server_cs.h> -#include <symbols_usrp_tx.h> -#include <symbols_usrp_rx.h> -#include <symbols_usrp_channel.h> -#include <symbols_usrp_low_level_cs.h> - -typedef usrp_inband_usb_packet transport_pkt; // makes conversion to gigabit easy - -static bool verbose = false; - -static pmt_t s_timeout = pmt_intern("%timeout"); - -// ---------------------------------------------------------------------------------------------- - -class qa_alloc_top : public mb_mblock -{ - mb_port_sptr d_tx; - mb_port_sptr d_rx; - mb_port_sptr d_cs; - - long d_nmsgs_to_recv; - long d_nrecvd; - - long d_max_capacity; - long d_ntx_chan, d_nrx_chan; - - long d_nstatus; - long d_nstatus_to_recv; - - public: - qa_alloc_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg); - ~qa_alloc_top(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - protected: - void check_message(mb_message_sptr msg); - void run_tests(); -}; - -qa_alloc_top::qa_alloc_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(runtime, instance_name, user_arg) -{ - d_nrecvd=0; - d_nmsgs_to_recv = 6; - d_nstatus=0; - d_nstatus_to_recv = 50; - - d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL); - d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL); - d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL); - - // Use the stub with the usrp_server - pmt_t usrp_server_dict = pmt_make_dict(); - pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T); - - // Test the TX side - define_component("server", "usrp_server", usrp_server_dict); - connect("self", "tx0", "server", "tx0"); - connect("self", "rx0", "server", "rx0"); - connect("self", "cs", "server", "cs"); - -} - -qa_alloc_top::~qa_alloc_top(){} - -void -qa_alloc_top::initial_transition() -{ - // Allocations should fail before open - d_tx->send(s_cmd_allocate_channel, - pmt_list2(pmt_list2(s_response_allocate_channel, - s_err_usrp_not_opened), - pmt_from_long(1))); - - d_rx->send(s_cmd_allocate_channel, - pmt_list2(pmt_list2(s_response_allocate_channel, - s_err_usrp_not_opened), - pmt_from_long(1))); - - // Retrieve information about the USRP, then run tests - d_cs->send(s_cmd_open, - pmt_list2(pmt_list2(s_response_open, PMT_T), - pmt_from_long(0))); - - d_cs->send(s_cmd_max_capacity, - pmt_list1(pmt_list2(s_response_max_capacity, PMT_T))); - - d_cs->send(s_cmd_ntx_chan, - pmt_list1(pmt_list2(s_response_ntx_chan, PMT_T))); - - d_cs->send(s_cmd_nrx_chan, - pmt_list1(pmt_list2(s_response_nrx_chan,PMT_T))); -} - -void -qa_alloc_top::run_tests() -{ - if(verbose) - std::cout << "[qa_alloc_top] Starting tests...\n"; - - // should be able to allocate 1 byte - d_tx->send(s_cmd_allocate_channel, - pmt_list2(PMT_T, pmt_from_long(1))); - - // should not be able to allocate max capacity after 100 bytes were allocated - d_tx->send(s_cmd_allocate_channel, - pmt_list2(s_err_requested_capacity_unavailable, - pmt_from_long(d_max_capacity))); - - // keep allocating a little more until all of the channels are used and test - // the error response we start at 1 since we've already allocated 1 channel - for(int i=1; i < d_ntx_chan; i++) { - - if(verbose) - std::cout << "[qa_alloc_top] Sent allocation request...\n"; - - d_tx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1))); - - d_nmsgs_to_recv++; - } - - // No more channels after allocating all of them is expected - d_tx->send(s_cmd_allocate_channel, - pmt_list2(s_err_channel_unavailable, - pmt_from_long(1))); - - // test out the same on the RX side - d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1))); - - d_rx->send(s_cmd_allocate_channel, - pmt_list2(s_err_requested_capacity_unavailable, - pmt_from_long(d_max_capacity))); - - for(int i=1; i < d_nrx_chan; i++) { - - d_rx->send(s_cmd_allocate_channel, pmt_list2(PMT_T, pmt_from_long(1))); - - d_nmsgs_to_recv++; - } - - d_rx->send(s_cmd_allocate_channel, - pmt_list2(s_err_channel_unavailable, - pmt_from_long(1))); - - // when all is said and done, there should be d_ntx_chan+d_ntx_chan bytes - // allocated - d_cs->send(s_cmd_current_capacity_allocation, - pmt_list1(pmt_from_long(d_ntx_chan+d_nrx_chan))); -} - -void -qa_alloc_top::handle_message(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - - if ((pmt_eq(msg->port_id(), d_tx->port_symbol()) - || pmt_eq(msg->port_id(), d_rx->port_symbol())) - && pmt_eq(msg->signal(), s_response_allocate_channel)) - check_message(msg); - - if (pmt_eq(msg->port_id(), d_cs->port_symbol())) { - - if(pmt_eq(msg->signal(), s_response_max_capacity)) { - d_max_capacity = pmt_to_long(pmt_nth(2, data)); - if(verbose) - std::cout << "[qa_alloc_top] USRP has max capacity of " - << d_max_capacity << "\n"; - } - else if(pmt_eq(msg->signal(), s_response_ntx_chan)) { - d_ntx_chan = pmt_to_long(pmt_nth(2, data)); - if(verbose) - std::cout << "[qa_alloc_top] USRP tx channels: " - << d_ntx_chan << "\n"; - } - else if(pmt_eq(msg->signal(), s_response_nrx_chan)) { - d_nrx_chan = pmt_to_long(pmt_nth(2, data)); - if(verbose) - std::cout << "[qa_alloc_top] USRP rx channels: " - << d_nrx_chan << "\n"; - } - else if(pmt_eq(msg->signal(), s_response_current_capacity_allocation)) { - check_message(msg); - } - - d_nstatus++; - - check_message(msg); - - if(d_nstatus==d_nstatus_to_recv) - run_tests(); - } -} - -void -qa_alloc_top::check_message(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - pmt_t event = msg->signal(); - - pmt_t expected = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - - pmt_t e_event = pmt_nth(0, expected); - pmt_t e_status = pmt_nth(1, expected); - - d_nrecvd++; - - - if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) { - if(verbose) - std::cout << "Got: " << status << " Expected: " << e_status << "\n"; - shutdown_all(PMT_F); - return; - } else { - if(verbose) - std::cout << "[qa_alloc_top] Received expected response for message " - << d_nrecvd << " (" << event << ")\n"; - } - - if(d_nrecvd == d_nmsgs_to_recv) - shutdown_all(PMT_T); -} - -REGISTER_MBLOCK_CLASS(qa_alloc_top); - -// ---------------------------------------------------------------------------------------------- - -class qa_dealloc_top : public mb_mblock -{ - mb_port_sptr d_tx; - mb_port_sptr d_rx; - mb_port_sptr d_cs; - - long d_max_capacity; - long d_ntx_chan, d_nrx_chan; - - long d_nstatus; - long d_nstatus_to_recv; - - long d_nalloc_to_recv; - long d_nalloc_recvd; - - long d_ndealloc_to_recv; - long d_ndealloc_recvd; - - std::vector<long> d_tx_chans; - std::vector<long> d_rx_chans; - - public: - qa_dealloc_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg); - ~qa_dealloc_top(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - protected: - void check_allocation(mb_message_sptr msg); - void check_deallocation(mb_message_sptr msg); - void allocate_max(); - void deallocate_all(); -}; - -qa_dealloc_top::qa_dealloc_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(runtime, instance_name, user_arg) -{ - d_ndealloc_recvd=0; - d_ndealloc_to_recv = 0; - d_nalloc_recvd=0; - d_nalloc_to_recv = 0; // auto-set - d_nstatus=0; - d_nstatus_to_recv = 4; - - d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL); - d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL); - d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL); - - // Use the stub with the usrp_server - pmt_t usrp_server_dict = pmt_make_dict(); - pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T); - - // Test the TX side - define_component("server", "usrp_server", usrp_server_dict); - connect("self", "tx0", "server", "tx0"); - connect("self", "rx0", "server", "rx0"); - connect("self", "cs", "server", "cs"); -} - -qa_dealloc_top::~qa_dealloc_top(){} - -void -qa_dealloc_top::initial_transition() -{ - - if(verbose) - std::cout << "[qa_dealloc_top] Initializing...\n"; - - // Retrieve information about the USRP, then run tests - d_cs->send(s_cmd_open, - pmt_list2(pmt_list2(s_response_open,PMT_T), - pmt_from_long(0))); - - d_cs->send(s_cmd_max_capacity, - pmt_list1(pmt_list2(s_response_max_capacity,PMT_T))); - - d_cs->send(s_cmd_ntx_chan, - pmt_list1(pmt_list2(s_response_ntx_chan,PMT_T))); - - d_cs->send(s_cmd_nrx_chan, - pmt_list1(pmt_list2(s_response_nrx_chan,PMT_T))); -} - -void -qa_dealloc_top::allocate_max() -{ - - // Keep allocating until we hit the maximum number of channels - for(int i=0; i < d_ntx_chan; i++) { - d_tx->send(s_cmd_allocate_channel, - pmt_list2(pmt_list2(s_response_allocate_channel,PMT_T), - pmt_from_long(1))); // 1 byte is good enough - - d_nalloc_to_recv++; - } - - for(int i=0; i < d_nrx_chan; i++) { - d_rx->send(s_cmd_allocate_channel, - pmt_list2(pmt_list2(s_response_allocate_channel,PMT_T), - pmt_from_long(1))); - - d_nalloc_to_recv++; - } - -} - -void -qa_dealloc_top::deallocate_all() { - - // Deallocate all of the channels that were allocated from allocate_max() - for(int i=0; i < (int)d_tx_chans.size(); i++) { - - if(verbose) - std::cout << "[qa_dealloc_top] Trying to dealloc TX " - << d_tx_chans[i] << std::endl; - - d_tx->send(s_cmd_deallocate_channel, - pmt_list2(pmt_list2(s_response_deallocate_channel,PMT_T), - pmt_from_long(d_tx_chans[i]))); - - d_ndealloc_to_recv++; - } - - // Deallocate the RX side now - for(int i=0; i < (int)d_rx_chans.size(); i++) { - - if(verbose) - std::cout << "[qa_dealloc_top] Trying to dealloc RX " - << d_tx_chans[i] << std::endl; - - d_rx->send(s_cmd_deallocate_channel, - pmt_list2(pmt_list2(s_response_deallocate_channel,PMT_T), - pmt_from_long(d_rx_chans[i]))); - - d_ndealloc_to_recv++; - } - - // Should get permission denied errors trying to re-dealloc the channels, as - // we no longer have permission to them after deallocating - for(int i=0; i < (int)d_tx_chans.size(); i++) { - - d_tx->send(s_cmd_deallocate_channel, - pmt_list2(pmt_list2(s_response_deallocate_channel, - s_err_channel_permission_denied), - pmt_from_long(d_tx_chans[i]))); - - d_ndealloc_to_recv++; - } - - // Same for RX - for(int i=0; i < (int)d_rx_chans.size(); i++) { - - d_rx->send(s_cmd_deallocate_channel, - pmt_list2(pmt_list2(s_response_deallocate_channel, - s_err_channel_permission_denied), - pmt_from_long(d_rx_chans[i]))); - - d_ndealloc_to_recv++; - } - - // Try to deallocate a channel that doesn't exist on both sides, the last - // element in the vectors is the highest channel number, so we take that plus - // 1 - d_ndealloc_to_recv+=2; - d_tx->send(s_cmd_deallocate_channel, - pmt_list2(pmt_list2(s_response_deallocate_channel, - s_err_channel_invalid), - pmt_from_long(d_rx_chans.back()+1))); - - d_rx->send(s_cmd_deallocate_channel, - pmt_list2(pmt_list2(s_response_deallocate_channel, - s_err_channel_invalid), - pmt_from_long(d_rx_chans.back()+1))); - - - // The used capacity should be back to 0 now that we've deallocated everything - d_cs->send(s_cmd_current_capacity_allocation, - pmt_list1(pmt_list2(s_response_current_capacity_allocation, - PMT_T))); -} - -void -qa_dealloc_top::handle_message(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - pmt_t event = msg->signal(); - - if(pmt_eq(event, pmt_intern("%shutdown"))) - return; - - pmt_t expected = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - - pmt_t e_event = pmt_nth(0, expected); - pmt_t e_status = pmt_nth(1, expected); - - if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) { - if(verbose) - std::cout << "Got: " << status << " Expected: " << e_status << "\n"; - shutdown_all(PMT_F); - return; - } else { - if(verbose) - std::cout << "[qa_alloc_top] Received expected response for message " - << d_ndealloc_recvd - << " (" << event << ")\n"; - } - - if (pmt_eq(msg->port_id(), d_tx->port_symbol()) - || pmt_eq(msg->port_id(), d_rx->port_symbol())) { - - if(pmt_eq(msg->signal(), s_response_allocate_channel)) { - check_allocation(msg); - } - - } - - if (pmt_eq(msg->port_id(), d_cs->port_symbol())) { - - if(pmt_eq(msg->signal(), s_response_max_capacity)) { - d_max_capacity = pmt_to_long(pmt_nth(2, data)); - } - else if(pmt_eq(msg->signal(), s_response_ntx_chan)) { - d_ntx_chan = pmt_to_long(pmt_nth(2, data)); - } - else if(pmt_eq(msg->signal(), s_response_nrx_chan)) { - d_nrx_chan = pmt_to_long(pmt_nth(2, data)); - } - else if(pmt_eq(msg->signal(), s_response_current_capacity_allocation)) { - // the final command is a capacity check which should be 0, then we - // shutdown - pmt_t expected_result = pmt_from_long(0); - pmt_t result = pmt_nth(2, data); - - if(pmt_eqv(expected_result, result)) { - shutdown_all(PMT_T); - return; - } else { - shutdown_all(PMT_F); - return; - } - } - - d_nstatus++; - - if(d_nstatus==d_nstatus_to_recv) - allocate_max(); - } -} - - -void -qa_dealloc_top::check_allocation(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - pmt_t event = msg->signal(); - - pmt_t expected = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - pmt_t channel = pmt_nth(2, data); - - d_nalloc_recvd++; - - if(!pmt_eqv(status, PMT_T)) { - shutdown_all(PMT_F); - return; - } else { - // store all of the allocate channel numbers - if(pmt_eq(msg->port_id(), d_tx->port_symbol())) - d_tx_chans.push_back(pmt_to_long(channel)); - if(pmt_eq(msg->port_id(), d_rx->port_symbol())) - d_rx_chans.push_back(pmt_to_long(channel)); - } - - if(d_nalloc_recvd == d_nalloc_to_recv) { - - if(verbose) { - std::cout << "[qa_dealloc_top] Allocated TX channels: "; - for(int i=0; i < (int)d_tx_chans.size(); i++) - std::cout << d_tx_chans[i] << " "; - - std::cout << "\n[qa_dealloc_top] Allocated RX channels: "; - for(int i=0; i < (int)d_rx_chans.size(); i++) - std::cout << d_rx_chans[i] << " "; - std::cout << "\n"; - } - - deallocate_all(); // once we've allocated all of our channels, try to - // dealloc them - } -} - -REGISTER_MBLOCK_CLASS(qa_dealloc_top); - -// ---------------------------------------------------------------------------------------------- - -class qa_open_close_top : public mb_mblock -{ - mb_port_sptr d_cs; - - long d_max_capacity; - - long d_nmsg_to_recv; - long d_nmsg_recvd; - - public: - qa_open_close_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg); - ~qa_open_close_top(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - protected: - void check_cs(mb_message_sptr msg); - void run_tests(); -}; - -qa_open_close_top::qa_open_close_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(runtime, instance_name, user_arg) -{ - - d_nmsg_to_recv=7; - d_nmsg_recvd=0; - - d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL); - - // Use the stub with the usrp_server - pmt_t usrp_server_dict = pmt_make_dict(); - pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T); - - // Test the TX side - define_component("server", "usrp_server", usrp_server_dict); - connect("self", "cs", "server", "cs"); -} - -qa_open_close_top::~qa_open_close_top(){} - -void -qa_open_close_top::initial_transition() -{ - run_tests(); -} - -void -qa_open_close_top::run_tests() -{ - // std::cout << "[qa_open_close_top] Starting tests\n"; - - // A close before an open should fail - d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close, - s_err_usrp_already_closed))); - - // Perform an open, and a second open which should fail - d_cs->send(s_cmd_open, - pmt_list2(pmt_list2(s_response_open,PMT_T), - pmt_from_long(0))); - - d_cs->send(s_cmd_open, - pmt_list2(pmt_list2(s_response_open, - s_err_usrp_already_opened), - pmt_from_long(0))); - - // A close should now be successful since the interface is open - d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T))); - - // But, a second close should fail - d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close, - s_err_usrp_already_closed))); - - // Just to be thorough, try an open and close again - d_cs->send(s_cmd_open, - pmt_list2(pmt_list2(s_response_open,PMT_T), - pmt_from_long(0))); - - d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T))); - -} - - -void -qa_open_close_top::handle_message(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - - if (pmt_eq(msg->port_id(), d_cs->port_symbol())) { - check_cs(msg); - } - - d_nmsg_recvd++; - - if(d_nmsg_to_recv == d_nmsg_recvd) - shutdown_all(PMT_T); -} - -void -qa_open_close_top::check_cs(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - pmt_t event = msg->signal(); - - pmt_t expected = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - - pmt_t e_event = pmt_nth(0, expected); - pmt_t e_status = pmt_nth(1, expected); - - if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) { - - if(verbose) - std::cout << "[qa_open_close_top] FAILED check_cs... Got: " << status - << " Expected: " << e_status - << " for event " << event << "\n"; - - shutdown_all(PMT_F); - } else { - if(verbose) - std::cout << "[qa_open_close_top] Received expected CS response (" - << event << ")\n"; - } - -} - -REGISTER_MBLOCK_CLASS(qa_open_close_top); - -// ---------------------------------------------------------------------------------------------- - -class qa_tx_top : public mb_mblock -{ - mb_port_sptr d_tx; - mb_port_sptr d_rx; - mb_port_sptr d_cs; - - long d_max_capacity; - long d_ntx_chan, d_nrx_chan; - - long d_tx_chan; - long d_rx_chan; - - long d_nmsg_to_recv; - long d_nmsg_recvd; - - public: - qa_tx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg); - ~qa_tx_top(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - protected: - void check_allocation(mb_message_sptr msg); - void check_deallocation(mb_message_sptr msg); - void check_xmit(mb_message_sptr msg); - void check_cs(mb_message_sptr msg); - void run_tests(); -}; - -qa_tx_top::qa_tx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(runtime, instance_name, user_arg) -{ - - d_nmsg_to_recv=10; - d_nmsg_recvd=0; - - d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL); - d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL); - d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL); - - // Use the stub with the usrp_server - pmt_t usrp_server_dict = pmt_make_dict(); - pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T); - - // Test the TX side - define_component("server", "usrp_server", usrp_server_dict); - connect("self", "tx0", "server", "tx0"); - connect("self", "rx0", "server", "rx0"); - connect("self", "cs", "server", "cs"); -} - -qa_tx_top::~qa_tx_top(){} - -void -qa_tx_top::initial_transition() -{ - run_tests(); -} - -void -qa_tx_top::run_tests() -{ - if(verbose) - std::cout << "[qa_tx_top] Starting tests\n"; - - // A transmit before an open should fail - d_tx->send(s_cmd_xmit_raw_frame, - pmt_list4(pmt_list2(s_response_xmit_raw_frame, - s_err_usrp_not_opened), - pmt_from_long(0), - pmt_make_u32vector(transport_pkt::max_payload()/4, 0), - pmt_from_long(0))); - - // Now open - d_cs->send(s_cmd_open, - pmt_list2(pmt_list2(s_response_open,PMT_T), - pmt_from_long(0))); - - // Try to transmit on a channel that we have no allocation for - d_tx->send(s_cmd_xmit_raw_frame, - pmt_list4(pmt_list2(s_response_xmit_raw_frame, - s_err_channel_permission_denied), - pmt_from_long(0), - pmt_make_u32vector(transport_pkt::max_payload()/4, 0), - pmt_from_long(0))); - - // Get a channel allocation and send on it, we assume 0 (FIXME) until 'defer' - // is implemented for simplicity - d_tx->send(s_cmd_allocate_channel, - pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), - pmt_from_long(1))); - - d_tx->send(s_cmd_xmit_raw_frame, - pmt_list4(pmt_list2(s_response_xmit_raw_frame, PMT_T), - pmt_from_long(0), - pmt_make_u32vector(transport_pkt::max_payload()/4, 0), - pmt_from_long(0))); - - // Close should be successful - d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T))); - - // After closing, a new transmit raw frame should fail again - d_tx->send(s_cmd_xmit_raw_frame, - pmt_list4(pmt_list2(s_response_xmit_raw_frame, - s_err_usrp_not_opened), - pmt_from_long(0), - pmt_make_u32vector(transport_pkt::max_payload()/4, 0), - pmt_from_long(0))); - - // Reopen and retry before getting an allocation, the first xmit should fail, - // after we allocate it should work again - d_cs->send(s_cmd_open, - pmt_list2(pmt_list2(s_response_open, PMT_T), - pmt_from_long(0))); - - d_tx->send(s_cmd_xmit_raw_frame, - pmt_list4(pmt_list2(s_response_xmit_raw_frame, - s_err_channel_permission_denied), - pmt_from_long(0), - pmt_make_u32vector(transport_pkt::max_payload()/4, 0), - pmt_from_long(0))); - - d_tx->send(s_cmd_allocate_channel, - pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), - pmt_from_long(1))); - - d_tx->send(s_cmd_xmit_raw_frame, - pmt_list4(pmt_list2(s_response_xmit_raw_frame,PMT_T), - pmt_from_long(0), - pmt_make_u32vector(transport_pkt::max_payload()/4, 0), - pmt_from_long(0))); - - // A final close which should be successful - d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T))); - -} - - -void -qa_tx_top::handle_message(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - pmt_t event = msg->signal(); - - if(pmt_eq(event, pmt_intern("%shutdown"))) - return; - - pmt_t expected = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - - pmt_t e_event = pmt_nth(0, expected); - pmt_t e_status = pmt_nth(1, expected); - - if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) { - if(verbose) - std::cout << "[qa_xmit_top] Got: " << status - << " Expected: " << e_status - << "For signal: " << event << "\n"; - shutdown_all(PMT_F); - return; - } else { - if(verbose) - std::cout << "[qa_xmit_top] Received expected response for message " - << d_nmsg_recvd - << " (" << event << ")\n"; - } - - if (pmt_eq(msg->port_id(), d_tx->port_symbol()) - || pmt_eq(msg->port_id(), d_rx->port_symbol())) { - - if(pmt_eq(msg->signal(), s_response_allocate_channel)) - check_allocation(msg); - - } - - d_nmsg_recvd++; - - if(d_nmsg_to_recv == d_nmsg_recvd){ - shutdown_all(PMT_T); - return; - } -} - -void -qa_tx_top::check_allocation(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - pmt_t event = msg->signal(); - - pmt_t expected = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - pmt_t channel = pmt_nth(2, data); - - if(pmt_eqv(status, PMT_T)) { - // store all of the allocate channel numbers - if(pmt_eq(msg->port_id(), d_tx->port_symbol())) - d_tx_chan = pmt_to_long(channel); - if(pmt_eq(msg->port_id(), d_rx->port_symbol())) - d_rx_chan = pmt_to_long(channel); - } -} - -REGISTER_MBLOCK_CLASS(qa_tx_top); - -// ---------------------------------------------------------------------------------------------- - -class qa_rx_top : public mb_mblock -{ - mb_port_sptr d_rx; - mb_port_sptr d_cs; - - long d_max_capacity; - long d_ntx_chan, d_nrx_chan; - - long d_rx_chan; - - bool d_got_response_recv; - - mb_time d_t0; - double d_delta_t; - - public: - qa_rx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg); - ~qa_rx_top(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - protected: - void check_allocation(mb_message_sptr msg); - void check_deallocation(mb_message_sptr msg); - void check_xmit(mb_message_sptr msg); - void check_cs(mb_message_sptr msg); - void run_tests(); -}; - -qa_rx_top::qa_rx_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(runtime, instance_name, user_arg), - d_got_response_recv(false) -{ - - d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL); - d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL); - - // Use the stub with the usrp_server - pmt_t usrp_dict = pmt_make_dict(); - // Set TX and RX interpolations - pmt_dict_set(usrp_dict, - pmt_intern("decim-rx"), - pmt_from_long(128)); - pmt_dict_set(usrp_dict, pmt_intern("fake-usrp"), PMT_T); - - // Test the TX side - define_component("server", "usrp_server", usrp_dict); - connect("self", "rx0", "server", "rx0"); - connect("self", "cs", "server", "cs"); -} - -qa_rx_top::~qa_rx_top(){} - -void -qa_rx_top::initial_transition() -{ - run_tests(); -} - -void -qa_rx_top::run_tests() -{ - if(verbose) - std::cout << "[qa_rx_top] Starting tests\n"; - - d_cs->send(s_cmd_open, pmt_list2(pmt_list2(s_response_open,PMT_T), pmt_from_long(0))); - - d_rx->send(s_cmd_allocate_channel, - pmt_list2(pmt_list2(s_response_allocate_channel,PMT_T), - pmt_from_long(1))); - - d_rx->send(s_cmd_start_recv_raw_samples, - pmt_list2(PMT_NIL, - pmt_from_long(0))); - - // Schedule a small timeout in which we expect to have received at least one - // packet worth of samples from the stub - d_t0 = mb_time::time(); - schedule_one_shot_timeout(d_t0 + 0.01, PMT_NIL); -} - - -void -qa_rx_top::handle_message(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - pmt_t event = msg->signal(); - - if(pmt_eq(event, pmt_intern("%shutdown"))) - return; - - pmt_t expected = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - - // If we get a timeout we shutdown - if(pmt_eq(event, s_timeout)) { - if(verbose) - std::cout << "[qa_rx_top] Got timeout\n"; - d_rx->send(s_cmd_stop_recv_raw_samples, - pmt_list2(PMT_NIL, - pmt_from_long(0))); - - d_cs->send(s_cmd_close, pmt_list1(pmt_list2(s_response_close,PMT_T))); - return; - } - - // For testing RX, an invocation handle is not generated by the stub, - // therefore the same approach for testing is not used. We simply - // expect all responses to be true. - if(pmt_eq(event, s_response_recv_raw_samples)) { - if(pmt_eqv(status, PMT_T)) { - - if(verbose) - std::cout << "[qa_rx_top] Received expected response for message " - << " (" << event << ")\n"; - - // All we want is 1 response receive! Can't guarantee exact numbers - d_got_response_recv = true; - } - else { - if(verbose) - std::cout << "Got: " << status << " Expected: " << PMT_T << "\n"; - shutdown_all(PMT_F); - } - return; - } - - pmt_t e_event = pmt_nth(0, expected); - pmt_t e_status = pmt_nth(1, expected); - - if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) { - if(verbose) - std::cout << "Got: " << status << " Expected: " << e_status << "\n"; - shutdown_all(PMT_F); - return; - } else { - if(verbose) - std::cout << "[qa_rx_top] Received expected response for message " - << " (" << event << ")\n"; - } - - if (pmt_eq(msg->port_id(), d_rx->port_symbol())) { - - if(pmt_eq(msg->signal(), s_response_allocate_channel)) - check_allocation(msg); - - } - - // We stop when we get a close, we are successful if we - // got a response from recv, fail if we never got a recv response - if(pmt_eq(msg->signal(), s_response_close)) { - - if(d_got_response_recv) { - shutdown_all(PMT_T); - return; - } - else { - shutdown_all(PMT_F); - if(verbose) - std::cout << "[qa_rx_top] No response message before close\n"; - return; - } - } -} - - -void -qa_rx_top::check_allocation(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - pmt_t event = msg->signal(); - - pmt_t expected = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - pmt_t channel = pmt_nth(2, data); - - if(pmt_eqv(status, PMT_T)) { - // store all of the allocate channel numbers - if(pmt_eq(msg->port_id(), d_rx->port_symbol())) - d_rx_chan = pmt_to_long(channel); - } -} - -REGISTER_MBLOCK_CLASS(qa_rx_top); - -// ---------------------------------------------------------------------------------------------- - -class qa_rid_top : public mb_mblock -{ - mb_port_sptr d_tx; - mb_port_sptr d_rx; - mb_port_sptr d_cs; - - long d_npongs; - long d_tcycles; - long d_cycles; - long d_max_rid; - - mb_time d_t0; - double d_delta_t; - - public: - qa_rid_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg); - ~qa_rid_top(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - protected: - void run_tests(); - void send_max_pings(); -}; - -qa_rid_top::qa_rid_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(runtime, instance_name, user_arg) -{ - d_npongs = 0; - d_tcycles = 3; - d_cycles = d_tcycles; - d_max_rid = usrp_server::D_MAX_RID; - d_delta_t = 0.1; - - - d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL); - d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL); - d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL); - - // Use the stub with the usrp_server - pmt_t usrp_server_dict = pmt_make_dict(); - pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T); - - // Test the TX side - define_component("server", "usrp_server", usrp_server_dict); - connect("self", "tx0", "server", "tx0"); - connect("self", "rx0", "server", "rx0"); - connect("self", "cs", "server", "cs"); - -} - -qa_rid_top::~qa_rid_top(){} - -void -qa_rid_top::initial_transition() -{ - run_tests(); -} - -void -qa_rid_top::run_tests() -{ - if(verbose) - std::cout << "[qa_rid_top] Starting tests...\n"; - - // Retrieve information about the USRP, then run tests - d_cs->send(s_cmd_open, - pmt_list2(pmt_list2(s_response_open, PMT_T), - pmt_from_long(0))); - - // should be able to allocate 1 byte - d_tx->send(s_cmd_allocate_channel, - pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), - pmt_from_long(1))); - - d_rx->send(s_cmd_allocate_channel, - pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), - pmt_from_long(1))); - - // Need to start receiving to read from the USRP to get C/S responses - d_rx->send(s_cmd_start_recv_raw_samples, - pmt_list2(PMT_NIL, - pmt_from_long(0))); - - // Build a subpacket of MAX_RID pings and wait a small amount for all of the - // responses and fire off another MAX_RID. If MAX_RID*2 responses are - // received, the RID recycling is working correctly. - // Schedule a timer in which we expect to have received all of the responses, - // which will send off another MAX_RID worth. - send_max_pings(); - d_t0 = mb_time::time(); - schedule_one_shot_timeout(d_t0 + d_delta_t, PMT_NIL); -} - -void -qa_rid_top::send_max_pings() -{ - pmt_t ping = pmt_list2(s_op_ping_fixed, - pmt_list2(pmt_from_long(0), - pmt_from_long(0))); - - pmt_t sub_packets = PMT_NIL; - - for(int i=0; i<d_max_rid; i++) - sub_packets = pmt_list_add(sub_packets, ping); - - d_tx->send(s_cmd_to_control_channel, - pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T), - sub_packets)); -} - -void -qa_rid_top::handle_message(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - pmt_t event = msg->signal(); - - // If we get a timeout we ensure we got a maximum RID number of responses. - if(pmt_eq(event, s_timeout)) { - if(verbose) - std::cout << "[qa_rid_top] Got timeout, received so far: " - << d_npongs << "\n"; - - d_cycles--; - - if(d_cycles==0 && d_npongs == d_max_rid*d_tcycles) { - shutdown_all(PMT_T); - } - else if(d_cycles==0) { - - std::cout << "[qa_rid_top] d_npongs: " << d_npongs - << " expected: " << d_max_rid*d_tcycles - << std::endl; - - shutdown_all(PMT_F); - } - else { - send_max_pings(); - d_t0 = mb_time::time(); - schedule_one_shot_timeout(d_t0 + d_delta_t, PMT_NIL); - } - - } - else if(pmt_eq(event, s_response_from_control_channel)) - { - d_npongs++; - } - -} - -REGISTER_MBLOCK_CLASS(qa_rid_top); - - -// ---------------------------------------------------------------------------------------------- - -class qa_cs_top : public mb_mblock -{ - mb_port_sptr d_tx; - mb_port_sptr d_rx; - mb_port_sptr d_cs; - - long d_nmsgs_to_recv; - long d_nrecvd; - - long d_max_capacity; - long d_ntx_chan, d_nrx_chan; - - long d_nstatus; - long d_nstatus_to_recv; - - public: - qa_cs_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg); - ~qa_cs_top(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - protected: - void check_message(mb_message_sptr msg); - void run_tests(); -}; - -qa_cs_top::qa_cs_top(mb_runtime *runtime, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(runtime, instance_name, user_arg) -{ - d_nrecvd=0; - d_nmsgs_to_recv = 8; - d_nstatus=0; - d_nstatus_to_recv = 50; - - d_rx = define_port("rx0", "usrp-rx", false, mb_port::INTERNAL); - d_tx = define_port("tx0", "usrp-tx", false, mb_port::INTERNAL); - d_cs = define_port("cs", "usrp-server-cs", false, mb_port::INTERNAL); - - // Use the stub with the usrp_server - pmt_t usrp_server_dict = pmt_make_dict(); - pmt_dict_set(usrp_server_dict, pmt_intern("fake-usrp"),PMT_T); - - // Test the TX side - define_component("server", "usrp_server", usrp_server_dict); - connect("self", "tx0", "server", "tx0"); - connect("self", "rx0", "server", "rx0"); - connect("self", "cs", "server", "cs"); - -} - -qa_cs_top::~qa_cs_top(){} - -void -qa_cs_top::initial_transition() -{ - run_tests(); -} - -void -qa_cs_top::run_tests() -{ - if(verbose) - std::cout << "[qa_cs_top] Starting tests...\n"; - - // Retrieve information about the USRP, then run tests - d_cs->send(s_cmd_open, - pmt_list2(pmt_list2(s_response_open, PMT_T), - pmt_from_long(0))); - - // should be able to allocate 1 byte - d_tx->send(s_cmd_allocate_channel, - pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), - pmt_from_long(1))); - - d_rx->send(s_cmd_allocate_channel, - pmt_list2(pmt_list2(s_response_allocate_channel, PMT_T), - pmt_from_long(1))); - - // Need to start receiving to read from the USRP to get C/S responses - d_rx->send(s_cmd_start_recv_raw_samples, - pmt_list2(PMT_NIL, - pmt_from_long(0))); - - d_tx->send(s_cmd_to_control_channel, - pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T), - pmt_list1( - pmt_list2(s_op_ping_fixed, - pmt_list2(pmt_from_long(3), - pmt_from_long(0)))))); - - d_tx->send(s_cmd_to_control_channel, - pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T), - pmt_list1( - pmt_list2(s_op_write_reg, - pmt_list2( - pmt_from_long(0x3), - pmt_from_long(0x4)))))); - - d_tx->send(s_cmd_to_control_channel, - pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T), - pmt_list1( - pmt_list2(s_op_write_reg_masked, - pmt_list3( - pmt_from_long(0x3), - pmt_from_long(0x4), - pmt_from_long(0x5)))))); - - d_tx->send(s_cmd_to_control_channel, - pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T), - pmt_list1( - pmt_list2(s_op_read_reg, - pmt_list2(pmt_from_long(0), - pmt_from_long(0x6)))))); - - d_tx->send(s_cmd_to_control_channel, - pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T), - pmt_list1( - pmt_list2(s_op_delay, - pmt_list1(pmt_from_long(0x7)))))); - - pmt_t subpackets = pmt_list5( - pmt_list2(s_op_ping_fixed, pmt_list2(pmt_from_long(0), pmt_from_long(0))), - pmt_list2(s_op_delay, pmt_list1(pmt_from_long(0x7))), - pmt_list2(s_op_write_reg_masked, pmt_list3(pmt_from_long(3), - pmt_from_long(4), - pmt_from_long(5))), - pmt_list2(s_op_write_reg, pmt_list2(pmt_from_long(3), - pmt_from_long(4))), - pmt_list2(s_op_read_reg, pmt_list2(pmt_from_long(0), - pmt_from_long(6))) - ); - - d_tx->send(s_cmd_to_control_channel, - pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T), - subpackets)); - - pmt_t i2c_data = pmt_make_u8vector(8, 0xff); - - subpackets = pmt_list2( - pmt_list2(s_op_i2c_write, - pmt_list2(pmt_from_long(8), i2c_data)), - pmt_list2(s_op_i2c_read, - pmt_list3(pmt_from_long(0), pmt_from_long(9), pmt_from_long(1))) - - ); - - d_tx->send(s_cmd_to_control_channel, - pmt_list2(pmt_list2(s_response_from_control_channel, PMT_T), - subpackets)); - -} - -void -qa_cs_top::handle_message(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - - if ((pmt_eq(msg->port_id(), d_tx->port_symbol()) - || pmt_eq(msg->port_id(), d_rx->port_symbol())) - && pmt_eq(msg->signal(), s_response_allocate_channel)) - check_message(msg); - - if (pmt_eq(msg->port_id(), d_tx->port_symbol()) - && pmt_eq(msg->signal(), s_response_from_control_channel)) - check_message(msg); - - if (pmt_eq(msg->port_id(), d_cs->port_symbol())) { - - if(pmt_eq(msg->signal(), s_response_max_capacity)) { - d_max_capacity = pmt_to_long(pmt_nth(2, data)); - if(verbose) - std::cout << "[qa_cs_top] USRP has max capacity of " - << d_max_capacity << "\n"; - } - else if(pmt_eq(msg->signal(), s_response_ntx_chan)) { - d_ntx_chan = pmt_to_long(pmt_nth(2, data)); - if(verbose) - std::cout << "[qa_cs_top] USRP tx channels: " - << d_ntx_chan << "\n"; - } - else if(pmt_eq(msg->signal(), s_response_nrx_chan)) { - d_nrx_chan = pmt_to_long(pmt_nth(2, data)); - if(verbose) - std::cout << "[qa_cs_top] USRP rx channels: " - << d_nrx_chan << "\n"; - } - else if(pmt_eq(msg->signal(), s_response_current_capacity_allocation)) { - check_message(msg); - } - - d_nstatus++; - - check_message(msg); - - if(d_nstatus==d_nstatus_to_recv) - run_tests(); - } -} - -void -qa_cs_top::check_message(mb_message_sptr msg) -{ - pmt_t data = msg->data(); - pmt_t event = msg->signal(); - - pmt_t expected = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - - pmt_t e_event = pmt_nth(0, expected); - pmt_t e_status = pmt_nth(1, expected); - - d_nrecvd++; - - - if(!pmt_eqv(e_status, status) || !pmt_eqv(e_event, event)) { - if(verbose) - std::cout << "[qa_cs_top] Got: " << status << " Expected: " << e_status << "\n"; - shutdown_all(PMT_F); - return; - } else { - if(verbose) - std::cout << "[qa_cs_top] Received expected response for message " - << d_nrecvd << " (" << event << ")\n"; - } - - if(d_nrecvd == d_nmsgs_to_recv) - shutdown_all(PMT_T); -} - -REGISTER_MBLOCK_CLASS(qa_cs_top); - -// ---------------------------------------------------------------------------------------------- - -void -qa_inband_usrp_server::test_open_close() -{ - mb_runtime_sptr rt = mb_make_runtime(); - pmt_t result = PMT_T; - - // std::cout << "\n\n----------------------------\n"; - // std::cout << " RUNNING OPEN/CLOSE TESTS \n"; - - rt->run("top", "qa_open_close_top", PMT_F, &result); - - CPPUNIT_ASSERT(pmt_equal(PMT_T, result)); -} - -void -qa_inband_usrp_server::test_chan_allocation() -{ - mb_runtime_sptr rt = mb_make_runtime(); - pmt_t result = PMT_T; - - // std::cout << "\n\n----------------------------\n"; - // std::cout << " RUNNING ALLOCATION TESTS \n"; - - rt->run("qa_alloc_top", "qa_alloc_top", PMT_F, &result); - - CPPUNIT_ASSERT(pmt_equal(PMT_T, result)); -} - -void -qa_inband_usrp_server::test_chan_deallocation() -{ - mb_runtime_sptr rt = mb_make_runtime(); - pmt_t result = PMT_T; - - // std::cout << "\n\n----------------------------\n"; - // std::cout << " RUNNING DEALLOCATION TESTS \n"; - - rt->run("qa_dealloc_top", "qa_dealloc_top", PMT_F, &result); - - CPPUNIT_ASSERT(pmt_equal(PMT_T, result)); -} - -void -qa_inband_usrp_server::test_tx() -{ - mb_runtime_sptr rt = mb_make_runtime(); - pmt_t result = PMT_T; - - // std::cout << "\n\n-----------------\n"; - // std::cout << " RUNNING TX TESTS \n"; - - rt->run("top", "qa_tx_top", PMT_F, &result); - - CPPUNIT_ASSERT(pmt_equal(PMT_T, result)); -} - -void -qa_inband_usrp_server::test_rx() -{ - mb_runtime_sptr rt = mb_make_runtime(); - pmt_t result = PMT_T; - - // std::cout << "\n\n-----------------\n"; - // std::cout << " RUNNING RX TESTS \n"; - - rt->run("top", "qa_rx_top", PMT_F, &result); - - CPPUNIT_ASSERT(pmt_equal(PMT_T, result)); -} - -void -qa_inband_usrp_server::test_cs() -{ - // FIXME This test is disabled because it hangs with the change to use usrp_standard_*_sptr's - return; - - mb_runtime_sptr rt = mb_make_runtime(); - pmt_t result = PMT_T; - - // std::cout << "\n\n-----------------\n"; - // std::cout << " RUNNING CS TESTS \n"; - - rt->run("top", "qa_cs_top", PMT_F, &result); - - CPPUNIT_ASSERT(pmt_equal(PMT_T, result)); -} - -void -qa_inband_usrp_server::test_rid() -{ - // FIXME This test is disabled because it hangs with the change to use usrp_standard_*_sptr's - return; - - mb_runtime_sptr rt = mb_make_runtime(); - pmt_t result = PMT_T; - - // std::cout << "\n\n-----------------\n"; - // std::cout << " RUNNING RID TESTS \n"; - - rt->run("top", "qa_rid_top", PMT_F, &result); - - CPPUNIT_ASSERT(pmt_equal(PMT_T, result)); -} diff --git a/usrp/limbo/inband/qa_inband_usrp_server.h b/usrp/limbo/inband/qa_inband_usrp_server.h deleted file mode 100644 index 52a4a0b06..000000000 --- a/usrp/limbo/inband/qa_inband_usrp_server.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef QA_INBAND_USRP_SERVER_H -#define QA_INBAND_USRP_SERVER_H - -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/TestCase.h> - -class qa_inband_usrp_server : public CppUnit::TestCase { - - CPPUNIT_TEST_SUITE(qa_inband_usrp_server); - CPPUNIT_TEST(test_open_close); - CPPUNIT_TEST(test_chan_allocation); - CPPUNIT_TEST(test_chan_deallocation); - CPPUNIT_TEST(test_tx); - CPPUNIT_TEST(test_rx); - CPPUNIT_TEST(test_cs); - CPPUNIT_TEST(test_rid); - CPPUNIT_TEST_SUITE_END(); - - private: - void test_chan_allocation(); - void test_chan_deallocation(); - void test_open_close(); - void test_tx(); - void test_rx(); - void test_cs(); - void test_rid(); -}; - -#endif /* INCLUDED_QA_INBAND_USRP_SERVER_H */ diff --git a/usrp/limbo/inband/symbols_usrp_channel.h b/usrp/limbo/inband/symbols_usrp_channel.h deleted file mode 100644 index a0114cf3c..000000000 --- a/usrp/limbo/inband/symbols_usrp_channel.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef INCLUDED_SYMBOLS_USRP_CHANNEL_H -#define INCLUDED_SYMBOLS_USRP_CHANNEL_H - -#include <pmt.h> - -// Outgoing -static pmt_t s_cmd_allocate_channel = pmt_intern("cmd-allocate-channel"); -static pmt_t s_cmd_deallocate_channel = pmt_intern("cmd-deallocate-channel"); - -// Incoming -static pmt_t s_response_allocate_channel = pmt_intern("response-allocate-channel"); -static pmt_t s_response_deallocate_channel = pmt_intern("response-deallocate-channel"); - -// Errors -static pmt_t s_err_requested_capacity_unavailable = pmt_intern("err-requested-capacity-unavailable"); -static pmt_t s_err_channel_unavailable = pmt_intern("err-channel-unavailable"); -static pmt_t s_err_channel_invalid = pmt_intern("err-channel-invalid"); -static pmt_t s_err_channel_permission_denied = pmt_intern("err-channel-permission-denied"); - -#endif /* INCLUDED_SYMBOLS_USRP_CHANNEL_H */ diff --git a/usrp/limbo/inband/symbols_usrp_interface_cs.h b/usrp/limbo/inband/symbols_usrp_interface_cs.h deleted file mode 100644 index 72c8fcc91..000000000 --- a/usrp/limbo/inband/symbols_usrp_interface_cs.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef INCLUDED_SYMBOLS_USRP_INTERFACE_CS_H -#define INCLUDED_SYMBOLS_USRP_INTERFACE_CS_H - -#include <pmt.h> - -// Outgoing -static pmt_t s_cmd_usrp_open = pmt_intern("cmd-usrp-open"); -static pmt_t s_cmd_usrp_close = pmt_intern("cmd-usrp-close"); -static pmt_t s_cmd_usrp_ntx_chan = pmt_intern("cmd-usrp-ntx-chan"); -static pmt_t s_cmd_usrp_nrx_chan = pmt_intern("cmd-usrp-nrx-chan"); -static pmt_t s_cmd_usrp_write = pmt_intern("cmd-usrp-write"); -static pmt_t s_cmd_usrp_start_reading = pmt_intern("cmd-usrp-start-reading"); -static pmt_t s_cmd_usrp_stop_reading = pmt_intern("cmd-usrp-stop-reading"); - -// Incoming -static pmt_t s_response_usrp_open = pmt_intern("response-usrp-open"); -static pmt_t s_response_usrp_close = pmt_intern("response-usrp-close"); -static pmt_t s_response_usrp_ntx_chan = pmt_intern("response-usrp-ntx-chan"); -static pmt_t s_response_usrp_nrx_chan = pmt_intern("response-usrp-nrx-chan"); -static pmt_t s_response_usrp_write = pmt_intern("response-usrp-write"); -static pmt_t s_response_usrp_read = pmt_intern("response-usrp-read"); - -#endif /* INCLUDED_SYMBOLS_USRP_INTERFACE_CS_H */ diff --git a/usrp/limbo/inband/symbols_usrp_low_level_cs.h b/usrp/limbo/inband/symbols_usrp_low_level_cs.h deleted file mode 100644 index a7260603a..000000000 --- a/usrp/limbo/inband/symbols_usrp_low_level_cs.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef INCLUDED_SYMBOLS_USRP_LOW_LEVEL_CS_H -#define INCLUDED_SYMBOLS_USRP_LOW_LEVEL_CS_H - -#include <pmt.h> - -// Outgoing -static pmt_t s_cmd_to_control_channel = pmt_intern("cmd-to-control-channel"); - -// Incoming -static pmt_t s_response_from_control_channel = pmt_intern("response-from-control-channel"); - -// Subpackets -static pmt_t s_op_ping_fixed = pmt_intern("op-ping-fixed"); -static pmt_t s_op_ping_fixed_reply = pmt_intern("op-ping-fixed-reply"); -static pmt_t s_op_write_reg = pmt_intern("op-write-reg"); -static pmt_t s_op_write_reg_masked = pmt_intern("op-write-reg-masked"); -static pmt_t s_op_read_reg = pmt_intern("op-read-reg"); -static pmt_t s_op_read_reg_reply = pmt_intern("op-read-reg-reply"); -static pmt_t s_op_i2c_write = pmt_intern("op-i2c-write"); -static pmt_t s_op_i2c_read = pmt_intern("op-i2c-read"); -static pmt_t s_op_i2c_read_reply = pmt_intern("op-i2c-read-reply"); -static pmt_t s_op_spi_write = pmt_intern("op-spi-write"); -static pmt_t s_op_spi_read = pmt_intern("op-spi-read"); -static pmt_t s_op_spi_read_reply = pmt_intern("op-spi-read-reply"); -static pmt_t s_op_delay = pmt_intern("op-delay"); - -#endif /* INCLUDED_SYMBOLS_USRP_LOW_LEVEL_CS_H */ diff --git a/usrp/limbo/inband/symbols_usrp_rx.h b/usrp/limbo/inband/symbols_usrp_rx.h deleted file mode 100644 index 07d58a3f5..000000000 --- a/usrp/limbo/inband/symbols_usrp_rx.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef INCLUDED_SYMBOLS_USRP_RX_H -#define INCLUDED_SYMBOLS_USRP_RX_H - -#include <pmt.h> - -// Outgoing -static pmt_t s_cmd_start_recv_raw_samples = pmt_intern("cmd-start-recv-raw-samples"); -static pmt_t s_cmd_stop_recv_raw_samples = pmt_intern("cmd-stop-recv-raw-samples"); - -// Incoming -static pmt_t s_response_recv_raw_samples = pmt_intern("response-recv-raw-samples"); - -// Errors -static pmt_t s_err_already_receiving = pmt_intern("err-already-receiving"); - -#endif /* INCLUDED_SYMBOLS_USRP_RX_H */ diff --git a/usrp/limbo/inband/symbols_usrp_rx_cs.h b/usrp/limbo/inband/symbols_usrp_rx_cs.h deleted file mode 100644 index bf4f0338b..000000000 --- a/usrp/limbo/inband/symbols_usrp_rx_cs.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef INCLUDED_SYMBOLS_USRP_RX_CS_H -#define INCLUDED_SYMBOLS_USRP_RX_CS_H - -#include <pmt.h> - -// Outgoing -static pmt_t s_cmd_usrp_rx_start_reading = pmt_intern("cmd-usrp-rx-start-reading"); - -// Incoming -static pmt_t s_response_usrp_rx_read = pmt_intern("response-usrp-rx-read"); - -#endif /* INCLUDED_SYMBOLS_USRP_RX_CS_H */ diff --git a/usrp/limbo/inband/symbols_usrp_server_cs.h b/usrp/limbo/inband/symbols_usrp_server_cs.h deleted file mode 100644 index e612e24ea..000000000 --- a/usrp/limbo/inband/symbols_usrp_server_cs.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef INCLUDED_SYMBOLS_USRP_SERVER_CS_H -#define INCLUDED_SYMBOLS_USRP_SERVER_CS_H - -#include <pmt.h> - -// Outgoing -static pmt_t s_cmd_open = pmt_intern("cmd-open"); -static pmt_t s_cmd_close = pmt_intern("cmd-close"); -static pmt_t s_cmd_max_capacity = pmt_intern("cmd-max-capacity"); -static pmt_t s_cmd_ntx_chan = pmt_intern("cmd-ntx-chan"); -static pmt_t s_cmd_nrx_chan = pmt_intern("cmd-nrx-chan"); -static pmt_t s_cmd_current_capacity_allocation = pmt_intern("cmd-current-capacity-allocation"); - -// Incoming -static pmt_t s_response_open = pmt_intern("response-open"); -static pmt_t s_response_close = pmt_intern("response-close"); -static pmt_t s_response_max_capacity = pmt_intern("response-max-capacity"); -static pmt_t s_response_ntx_chan = pmt_intern("response-ntx-chan"); -static pmt_t s_response_nrx_chan = pmt_intern("response-nrx-chan"); -static pmt_t s_response_current_capacity_allocation = pmt_intern("response-current-capacity-allocation"); - -// Errors -static pmt_t s_err_usrp_not_opened = pmt_intern("err-usrp-not-opened"); -static pmt_t s_err_usrp_already_opened = pmt_intern("err-usrp-already-opened"); -static pmt_t s_err_usrp_already_closed = pmt_intern("err-usrp-already-closed"); - -#endif /* INCLUDED_SYMBOLS_USRP_SERVER_CS_H */ diff --git a/usrp/limbo/inband/symbols_usrp_tx.h b/usrp/limbo/inband/symbols_usrp_tx.h deleted file mode 100644 index 4e58e2cf9..000000000 --- a/usrp/limbo/inband/symbols_usrp_tx.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef INCLUDED_SYMBOLS_USRP_TX_H -#define INCLUDED_SYMBOLS_USRP_TX_H - -#include <pmt.h> - -// Outgoing -static pmt_t s_cmd_xmit_raw_frame = pmt_intern("cmd-xmit-raw-frame"); - -// Incoming -static pmt_t s_response_xmit_raw_frame = pmt_intern("response-xmit-raw-frame"); - -#endif /* INCLUDED_SYMBOLS_USRP_TX_H */ diff --git a/usrp/limbo/inband/symbols_usrp_tx_cs.h b/usrp/limbo/inband/symbols_usrp_tx_cs.h deleted file mode 100644 index d02ef1d26..000000000 --- a/usrp/limbo/inband/symbols_usrp_tx_cs.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef INCLUDED_SYMBOLS_USRP_TX_CS_H -#define INCLUDED_SYMBOLS_USRP_TX_CS_H - -#include <pmt.h> - -// Outgoing -static pmt_t s_cmd_usrp_tx_write = pmt_intern("cmd-usrp-tx-write"); - -// Incoming -static pmt_t s_response_usrp_tx_write = pmt_intern("response-usrp-tx-write"); - -#endif /* INCLUDED_SYMBOLS_USRP_TX_CS_H */ diff --git a/usrp/limbo/inband/test_inband.cc b/usrp/limbo/inband/test_inband.cc deleted file mode 100644 index 77cdca556..000000000 --- a/usrp/limbo/inband/test_inband.cc +++ /dev/null @@ -1,36 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <cppunit/TextTestRunner.h> -#include <qa_inband.h> - -int -main(int argc, char **argv) -{ - - CppUnit::TextTestRunner runner; - - runner.addTest(qa_inband::suite ()); - - bool was_successful = runner.run("", false); - - return was_successful ? 0 : 1; -} diff --git a/usrp/limbo/inband/usb_packet.py b/usrp/limbo/inband/usb_packet.py deleted file mode 100644 index 6dfcf8638..000000000 --- a/usrp/limbo/inband/usb_packet.py +++ /dev/null @@ -1,115 +0,0 @@ -# -# Copyright 2007 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# - -import struct - - -FL_OVERRUN = 0x80000000 -FL_UNDERRUN = 0x40000000 -FL_DROPPED = 0x20000000 -FL_END_OF_BURST = 0x10000000 -FL_START_OF_BURST = 0x08000000 - -FL_ALL_FLAGS = 0xf8000000 - -FL_OVERRUN_SHIFT = 31 -FL_UNDERRUN_SHIFT = 30 -FL_DROPPED_SHIFT = 29 -FL_END_OF_BURST_SHIFT = 28 -FL_START_OF_BURST_SHIFT = 27 - -RSSI_MASK = 0x3f -RSSI_SHIFT = 21 - -CHAN_MASK = 0x1f -CHAN_SHIFT = 16 - -TAG_MASK = 0xf -TAG_SHIFT = 9 - -PAYLOAD_LEN_MASK = 0x1ff -PAYLOAD_LEN_SHIFT = 0 - -def make_header(flags, chan, payload_len, timestamp, rssi=0, tag=0): - word0 = ((flags & FL_ALL_FLAGS) - | ((rssi & RSSI_MASK) << RSSI_SHIFT) - | ((chan & CHAN_MASK) << CHAN_SHIFT) - | ((tag & TAG_MASK) << TAG_SHIFT) - | ((payload_len & PAYLOAD_LEN_MASK) << PAYLOAD_LEN_SHIFT)) - word1 = timestamp - return struct.pack('<2I', word0, word1) - - -def _decode(pred, indicator): - if pred: - return indicator - else: - return '-' - - -class usb_packet(object): - def __init__(self, raw_pkt): - assert isinstance(raw_pkt, str) and len(raw_pkt) == 512 - self._raw_pkt = raw_pkt; - (self._word0, self._word1) = struct.unpack('<2I', self._raw_pkt[0:8]) - - def timestamp(self): - return self._word1 - - def rssi(self): - return (self._word0 >> RSSI_SHIFT) & RSSI_MASK - - def chan(self): - return (self._word0 >> CHAN_SHIFT) & CHAN_MASK - - def tag(self): - return (self._word0 >> TAG_SHIFT) & TAG_MASK - - def payload_len(self): - return (self._word0 >> PAYLOAD_LEN_SHIFT) & PAYLOAD_LEN_MASK - - def flags(self): - return self._word0 & FL_ALL_FLAGS - - def overrun(self): - return (self._word0 >> FL_OVERRUN_SHIFT) & 0x1 - - def underrun(self): - return (self._word0 >> FL_UNDERRUN_SHIFT) & 0x1 - - def start_of_burst(self): - return (self._word0 >> FL_START_OF_BURST_SHIFT) & 0x1 - - def end_of_burst(self): - return (self._word0 >> FL_END_OF_BURST_SHIFT) & 0x1 - - def dropped(self): - return (self._word0 >> FL_DROPPED_SHIFT) & 0x1 - - def payload(self): - return self._raw_pkt[8:8+self.payload_len()] - - def decoded_flags(self): - s = (_decode(self.overrun(), 'O') - + _decode(self.underrun(), 'U') - + _decode(self.dropped(), 'D') - + _decode(self.end_of_burst(), 'E') - + _decode(self.start_of_burst(), 'S')) - return s diff --git a/usrp/limbo/inband/usrp_inband_usb_packet.cc b/usrp/limbo/inband/usrp_inband_usb_packet.cc deleted file mode 100644 index 72bc45ccb..000000000 --- a/usrp/limbo/inband/usrp_inband_usb_packet.cc +++ /dev/null @@ -1,793 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <usrp_inband_usb_packet.h> - -#include <usrp_bytesex.h> -#include <iostream> -#include <stdio.h> -#include <string.h> - -/*! - * \brief Aligns the packet payload on a 32 bit boundary. This is essential to - * all control/status packets so that the inband FPGA code can parse them - * easily. - * - * \returns true if successful or if the packet was already aligned; false if it - * cannot be aligned. - */ -bool usrp_inband_usb_packet::align32() -{ - int p_len = payload_len(); - - int bytes_needed = 4 - (p_len % 4); - - if(bytes_needed == 4) - return true; - - // If the room left in the packet is less than the number of bytes - // needed, return false to indicate no room to align - if((MAX_PAYLOAD - p_len) < bytes_needed) - return false; - - incr_header_len(bytes_needed); - - return true; -} - -/*! - * \brief Adds a ping command to the current control packet. - * - * The \p rid is the rid to be associated with the ping response and \p ping_val - * is currently unused. - * - * \returns true if adding the ping command was successful, false otherwise - * (i.e. no space in the current packet). - */ -bool usrp_inband_usb_packet::cs_ping(long rid, long ping_val) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - if((MAX_PAYLOAD - p_len) < (CS_PING_LEN + CS_FIXED_LEN)) - return false; - - uint32_t ping = ( - ((OP_PING_FIXED & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((CS_PING_LEN & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((rid & CS_RID_MASK) << CS_RID_SHIFT) - | (ping_val & CS_PINGVAL_MASK) - - ); - - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(ping); - - // Update payload length - incr_header_len(CS_FIXED_LEN + CS_PING_LEN); - - return true; -} - -/*! - * \brief Adds a ping response to the packet. This is used by the fake USRP - * code to generate fake responses for pings. - * - * The \p rid is the RID to be associated with the response and \p ping_val is - * currently unused. - * - * \returns true if the ping reply was added successfully, false otherwise. - */ -bool usrp_inband_usb_packet::cs_ping_reply(long rid, long ping_val) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - if((MAX_PAYLOAD - p_len) < (CS_PING_LEN + CS_FIXED_LEN)) - return false; - - uint32_t ping = ( - ((OP_PING_FIXED_REPLY & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((CS_PING_LEN & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((rid & CS_RID_MASK) << CS_RID_SHIFT) - | ((ping_val & CS_PINGVAL_MASK) << CS_PINGVAL_SHIFT) - - ); - - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(ping); - - // Update payload length - incr_header_len(CS_FIXED_LEN + CS_PING_LEN); - - return true; -} - -/*! - * \brief Adds a write register command to the packet. - * - * The \p reg_num is the register number for which the value \p val will be - * written to. - * - * \returns true if the command was added to the packet successfully, false - * otherwise. - */ -bool usrp_inband_usb_packet::cs_write_reg(long reg_num, long val) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - if((MAX_PAYLOAD - p_len) < (CS_WRITEREG_LEN + CS_FIXED_LEN)) - return false; - - uint32_t word0 = 0; - - // Build the first word which includes the register number - word0 = ( - ((OP_WRITE_REG & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((CS_WRITEREG_LEN & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((reg_num & CS_REGNUM_MASK) << CS_REGNUM_SHIFT) - ); - - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word0); - - // The second word is solely the register value to be written - // FIXME: should this be unsigned? - payload += 1; - *payload = host_to_usrp_u32((uint32_t) val); - - // Rebuild the header to update the payload length - incr_header_len(CS_FIXED_LEN + CS_WRITEREG_LEN); - - return true; -} - -/*! - * \brief Adds a write register masked command to the packet. - * - * The \p reg_num is the register number for which the value \p val will be - * written, masked by \p mask - * - * \returns true if the command was added to the packet, false otherwise. - */ -bool usrp_inband_usb_packet::cs_write_reg_masked(long reg_num, long val, long mask) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - if((MAX_PAYLOAD - p_len) < (CS_WRITEREGMASKED_LEN + CS_FIXED_LEN)) - return false; - - uint32_t word0 = 0; - - // Build the first word which includes the register number - word0 = ( - ((OP_WRITE_REG_MASKED & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((CS_WRITEREGMASKED_LEN & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((reg_num & CS_REGNUM_MASK) << CS_REGNUM_SHIFT) - ); - - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word0); - - // Skip over the first word and write the register value - payload += 1; - *payload = host_to_usrp_u32((uint32_t) val); - - // Skip over the register value and write the mask - payload += 1; - *payload = host_to_usrp_u32((uint32_t) mask); - - // Rebuild the header to update the payload length - incr_header_len(CS_FIXED_LEN + CS_WRITEREGMASKED_LEN); - - return true; -} - -/*! - * \brief Adds a read register message to the packet. - * - * The \p rid will be the associated RID returned with the response, and \p - * reg_num is the register to be read. - * - * \returns true if the command was added to the packet, false otherwise. - */ -bool usrp_inband_usb_packet::cs_read_reg(long rid, long reg_num) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - if((MAX_PAYLOAD - p_len) < (CS_READREG_LEN + CS_FIXED_LEN)) - return false; - - uint32_t read_reg = ( - ((OP_READ_REG & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((CS_READREG_LEN & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((rid & CS_RID_MASK) << CS_RID_SHIFT) - | ((reg_num & CS_REGNUM_MASK) << CS_REGNUM_SHIFT) - - ); - - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(read_reg); - - // Update payload length - incr_header_len(CS_FIXED_LEN + CS_READREG_LEN); - - return true; -} - -/*! - * \brief Adds a read register reply response to the current packet. This is - * used by the fake USRP code to generate fake register read responses for - * testing. - * - * The \p rid is the associated RID to be included in the response, \p reg_num - * is the register the read is coming from, and \p reg_val is the value of the - * read. - * - * \returns true if the command was added to the packet, false otherwise. - */ -bool usrp_inband_usb_packet::cs_read_reg_reply(long rid, long reg_num, long reg_val) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - if((MAX_PAYLOAD - p_len) < (CS_READREGREPLY_LEN + CS_FIXED_LEN)) - return false; - - uint32_t word0 = ( - ((OP_READ_REG_REPLY & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((CS_READREGREPLY_LEN & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((rid & CS_RID_MASK) << CS_RID_SHIFT) - | ((reg_num & CS_REGNUM_MASK) << CS_REGNUM_SHIFT) - - ); - - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word0); - - // Hop to the next word and write the reg value - payload += 1; - *payload = host_to_usrp_u32((uint32_t) reg_val); - - // Update payload length - incr_header_len(CS_FIXED_LEN + CS_READREGREPLY_LEN); - - return true; -} - -/*! - * \brief Adds a delay command to the current packet. - * - * The \p ticks parameter is the number of clock ticks the FPGA should delay - * parsing for, which is added to the packet. - * - * \returns true if the command was added to the packet, false otherwise. - */ -bool usrp_inband_usb_packet::cs_delay(long ticks) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - if((MAX_PAYLOAD - p_len) < (CS_DELAY_LEN + CS_FIXED_LEN)) - return false; - - uint32_t delay = ( - ((OP_DELAY & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((CS_DELAY_LEN & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((ticks & CS_DELAY_MASK) << CS_DELAY_SHIFT) - - ); - - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(delay); - - // Update payload length - incr_header_len(CS_FIXED_LEN + CS_DELAY_LEN); - - return true; -} - -/*! - * \brief - * - * \returns true if the command was added to the packet, false otherwise. - */ -bool usrp_inband_usb_packet::cs_i2c_write(long i2c_addr, uint8_t *i2c_data, size_t data_len) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - int i2c_len = data_len + 2; // 2 bytes between mbz and addr - - if((MAX_PAYLOAD - p_len) < (i2c_len + CS_FIXED_LEN)) - return false; - - uint32_t word0 = 0; - - word0 = ( - ((OP_I2C_WRITE & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((i2c_len & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((i2c_addr & CS_I2CADDR_MASK) << CS_I2CADDR_SHIFT) - ); - - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word0); - - // Jump over the first word and write the data - // FIXME: Should the data be changed to usrp byte order? - payload += 1; - memcpy(payload, i2c_data, data_len); - - // Update payload length - incr_header_len(CS_FIXED_LEN + i2c_len); - - return true; -} - -/*! - * \brief Adds an I2C read command to the current packet. - * - * The \p rid is the associated RID to return with the read response, \p - * i2c_addr is the address to read from on the I2C bus, and \p n_bytes is the - * number of bytes to be read from the bus. - * - * \returns true if the command was added to the packet, false otherwise. - */ -bool usrp_inband_usb_packet::cs_i2c_read(long rid, long i2c_addr, long n_bytes) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - if((MAX_PAYLOAD - p_len) < (CS_I2CREAD_LEN + CS_FIXED_LEN)) - return false; - - uint32_t word0 = 0; - - word0 = ( - ((OP_I2C_READ & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((CS_I2CREAD_LEN & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((rid & CS_RID_MASK) << CS_RID_SHIFT) - | ((i2c_addr & CS_I2CADDR_MASK) << CS_I2CADDR_SHIFT) - ); - - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word0); - - // Jump a word and write the number of bytes to read - payload += 1; - uint32_t word1 = - (n_bytes & CS_I2CREADBYTES_MASK) << CS_I2CREADBYTES_SHIFT; - *payload = host_to_usrp_u32(word1); - - // Update payload length - incr_header_len(CS_FIXED_LEN + CS_I2CREAD_LEN); - - return true; -} - -/*! - * \brief Adds an I2C read reply response to the current packet. This is used - * by the fake USRP code to generate fake I2C responses. - * - * The \p rid is the RID to be associated with the response, \p i2c_addr is the - * address on the I2C bus that the \p i2c_data of \p i2c_data_len was read from. - * - * \returns true if the command was added to the packet, false otherwise. - */ -bool usrp_inband_usb_packet::cs_i2c_read_reply(long rid, long i2c_addr, uint8_t *i2c_data, long i2c_data_len) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - int i2c_len = i2c_data_len + 2; - - if((MAX_PAYLOAD - p_len) < (i2c_len + CS_FIXED_LEN)) - return false; - - uint32_t word0 = 0; - - word0 = ( - ((OP_I2C_READ_REPLY & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((i2c_len & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((rid & CS_RID_MASK) << CS_RID_SHIFT) - | ((i2c_addr & CS_I2CADDR_MASK) << CS_I2CADDR_SHIFT) - ); - - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word0); - - // Jump a word and write the actual data - payload += 1; - memcpy(payload, i2c_data, i2c_data_len); - - // Update payload length - incr_header_len(CS_FIXED_LEN + i2c_len); - - return true; -} - -/*! - * \brief Adds a SPI write command to the current packet. - * - * \returns true if the command was added to the packet, false otherwise. - */ -bool usrp_inband_usb_packet::cs_spi_write(long enables, long format, long opt_header_bytes, uint8_t *spi_data, long spi_data_len) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - int spi_len = spi_data_len + 6; - - if((MAX_PAYLOAD - p_len) < (spi_len + CS_FIXED_LEN)) - return false; - - uint32_t word = 0; - - // First word contains the opcode and length, then mbz - word = ( - ((OP_SPI_WRITE & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((spi_len & CS_LEN_MASK) << CS_LEN_SHIFT) - ); - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word); - - payload += 1; - - // Second word contains the enables, format, and optional tx bytes - word = 0; - word = ( - ((enables & CS_SPIENABLES_MASK) << CS_SPIENABLES_SHIFT) - | ((format & CS_SPIFORMAT_MASK) << CS_SPIFORMAT_SHIFT) - | ((opt_header_bytes & CS_SPIOPT_MASK) << CS_SPIOPT_SHIFT) - ); - payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word); - - payload += 1; - memcpy(payload, spi_data, spi_data_len); - - // Update payload length - incr_header_len(CS_FIXED_LEN + spi_len); - - return true; -} - -/*! - * \brief Adds a SPI bus read command to the packet. - * - * \returns true if the command was added to the packet, false otherwise. - */ -bool usrp_inband_usb_packet::cs_spi_read(long rid, long enables, long format, long opt_header_bytes, long n_bytes) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - if((MAX_PAYLOAD - p_len) < (CS_SPIREAD_LEN + CS_FIXED_LEN)) - return false; - - uint32_t word = 0; - - // First word contains the opcode, length, and RID - word = ( - ((OP_SPI_READ & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((CS_SPIREAD_LEN & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((rid & CS_RID_MASK) << CS_RID_SHIFT) - ); - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word); - - payload += 1; - - // Second word contains the enables, format, and optional tx bytes - word = 0; - word = ( - ((enables & CS_SPIENABLES_MASK) << CS_SPIENABLES_SHIFT) - | ((format & CS_SPIFORMAT_MASK) << CS_SPIFORMAT_SHIFT) - | ((opt_header_bytes & CS_SPIOPT_MASK) << CS_SPIOPT_SHIFT) - ); - payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word); - - payload += 1; - - // The third word contains the number of bytes - word = 0; - word = ( - ((n_bytes & CS_SPINBYTES_MASK) << CS_SPINBYTES_SHIFT) - ); - payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word); - - // Update payload length - incr_header_len(CS_FIXED_LEN + CS_SPIREAD_LEN); - - return true; -} - -/*! - * \brief Adds an SPI read reply to the current packet. This is used by the - * fake USRP code to generate fake responses for SPI reads. - * - * \returns true if the command was added to the packet, false otherwise. - */ -bool usrp_inband_usb_packet::cs_spi_read_reply(long rid, uint8_t *spi_data, long spi_data_len) -{ - if(!align32()) - return false; - - int p_len = payload_len(); - - int spi_len = spi_data_len + 2; - - if((MAX_PAYLOAD - p_len) < (spi_len + CS_FIXED_LEN)) - return false; - - uint32_t word = 0; - - // First word contains the opcode, length, and RID - word = ( - ((OP_SPI_READ_REPLY & CS_OPCODE_MASK) << CS_OPCODE_SHIFT) - | ((spi_len & CS_LEN_MASK) << CS_LEN_SHIFT) - | ((rid & CS_RID_MASK) << CS_RID_SHIFT) - ); - uint32_t *payload = (uint32_t *) (d_payload + p_len); - *payload = host_to_usrp_u32(word); - - // Jump a word and write the actual data - payload += 1; - memcpy(payload, spi_data, spi_data_len); - - // Update payload length - incr_header_len(CS_FIXED_LEN + spi_len); - - return true; -} - -/*! - * \brief Since all control packets contain subpackets which have the length of - * the subpacket at a uniform location in the subpacket, this will return the - * subpacket length given a byte offset of the start of the subpacket from the beginning of the packet. - * - * \returns the length of the subpacket - */ -int usrp_inband_usb_packet::cs_len(int payload_offset) { - uint32_t subpkt = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset))); - return (subpkt >> CS_LEN_SHIFT) & CS_LEN_MASK; -} - -/*! - * \brief The following method takes an offset within the packet payload to - * extract a control/status subpacket and constructs a pmt response which - * includes the proper signal and arguments specified by usrp-low-level-cs. The - * USRP server could therefore use this to read subpackets and pass them - * responses back up to the application. It's arguable that only reply packets - * should be parsed here, however we parse others for use in debugging or - * failure reporting on the transmit side of packets. - */ -pmt_t usrp_inband_usb_packet::read_subpacket(int payload_offset) { - - uint32_t subpkt = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset))); - uint32_t opcode = (subpkt >> CS_OPCODE_SHIFT) & CS_OPCODE_MASK; - uint32_t len = (subpkt >> CS_LEN_SHIFT) & CS_LEN_MASK; - - switch(opcode) { - - case OP_PING_FIXED_REPLY: - { - pmt_t rid = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK); - pmt_t pingval = pmt_from_long((subpkt >> CS_PINGVAL_SHIFT) & CS_PINGVAL_MASK); - return pmt_list3(s_op_ping_fixed_reply, rid, pingval); - } - - case OP_READ_REG_REPLY: - { - pmt_t rid = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK); - pmt_t reg_num = pmt_from_long((subpkt >> CS_REGNUM_SHIFT) & CS_REGNUM_MASK); - - // To get the register value we just read the next 32 bits - uint32_t val = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4))); - pmt_t reg_val = pmt_from_long(val); - - return pmt_list4(s_op_read_reg_reply, rid, reg_num, reg_val); - } - - case OP_I2C_READ_REPLY: - { - pmt_t rid = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK); - pmt_t i2c_addr = pmt_from_long((subpkt >> CS_I2CADDR_SHIFT) & CS_I2CADDR_MASK); - - // Make a u8 vector to dump the data from the packet into - size_t i2c_data_len; - pmt_t i2c_data = pmt_make_u8vector(len - 2, 0); // skip rid+mbz+addr = 2 bytes - uint8_t *w_data = - (uint8_t *) pmt_u8vector_writable_elements(i2c_data, i2c_data_len); - - memcpy(w_data, d_payload + payload_offset + 4, i2c_data_len); // skip first word - - return pmt_list4(s_op_i2c_read_reply, rid, i2c_addr, i2c_data); - } - - case OP_SPI_READ_REPLY: - { - pmt_t rid = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK); - - // Make a u8 vector to dump the data from the packet into - size_t spi_data_len; - pmt_t spi_data = pmt_make_u8vector(len - 2, 0); // skip rid+mbz+addr = 2 bytes - uint8_t *w_data = - (uint8_t *) pmt_u8vector_writable_elements(spi_data, spi_data_len); - - memcpy(w_data, d_payload + payload_offset + 4, spi_data_len); // skip first word - - return pmt_list3(s_op_spi_read_reply, rid, spi_data); - } - - case OP_PING_FIXED: - { - pmt_t rid = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK); - pmt_t pingval = pmt_from_long((subpkt >> CS_PINGVAL_SHIFT) & CS_PINGVAL_MASK); - return pmt_list3(s_op_ping_fixed, rid, pingval); - } - - case OP_WRITE_REG: - { - pmt_t reg_num = pmt_from_long((subpkt >> CS_REGNUM_SHIFT) & CS_REGNUM_MASK); - - // To get the register value we just read the next 32 bits - uint32_t val = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4))); - pmt_t reg_val = pmt_from_long(val); - - return pmt_list3(s_op_write_reg, reg_num, reg_val); - } - - case OP_WRITE_REG_MASKED: - { - pmt_t reg_num = pmt_from_long((subpkt >> CS_REGNUM_SHIFT) & CS_REGNUM_MASK); - - // To get the register value we just read the next 32 bits - uint32_t val = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4))); - pmt_t reg_val = pmt_from_long(val); - - // The mask is the next 32 bits - uint32_t mask = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 8))); - pmt_t reg_mask = pmt_from_long(mask); - - return pmt_list4(s_op_write_reg_masked, reg_num, reg_val, reg_mask); - } - - case OP_READ_REG: - { - pmt_t rid = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK); - pmt_t reg_num = pmt_from_long((subpkt >> CS_REGNUM_SHIFT) & CS_REGNUM_MASK); - - return pmt_list3(s_op_read_reg, rid, reg_num); - } - - case OP_I2C_WRITE: - { - pmt_t i2c_addr = pmt_from_long((subpkt >> CS_I2CADDR_SHIFT) & CS_I2CADDR_MASK); - - // The length includes an extra 2 bytes for storing the mbz and addr - pmt_t i2c_data = pmt_make_u8vector(len-2, 0); - - // Get a writable address to copy the data from the packet - size_t ignore; - uint8_t *w_data = (uint8_t *) pmt_u8vector_writable_elements(i2c_data, ignore); - memcpy(w_data, d_payload + payload_offset + 4, len-2); - - - return pmt_list3(s_op_i2c_write, i2c_addr, i2c_data); - } - - case OP_I2C_READ: - { - pmt_t rid = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK); - pmt_t i2c_addr = pmt_from_long((subpkt >> CS_I2CADDR_SHIFT) & CS_I2CADDR_MASK); - - // The number of bytes is in the next word - uint32_t bytes = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4))); - bytes = (bytes >> CS_I2CREADBYTES_SHIFT) & CS_I2CREADBYTES_MASK; - pmt_t i2c_bytes = pmt_from_long(bytes); - - return pmt_list4(s_op_i2c_read, rid, i2c_addr, i2c_bytes); - } - - case OP_SPI_WRITE: - { - // Nothing interesting in the first word, skip to the next - uint32_t word = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4))); - pmt_t enables = pmt_from_long((word >> CS_SPIENABLES_SHIFT) & CS_SPIENABLES_MASK); - pmt_t format = pmt_from_long((word >> CS_SPIFORMAT_SHIFT) & CS_SPIFORMAT_MASK); - pmt_t opt = pmt_from_long((word >> CS_SPIOPT_SHIFT) & CS_SPIOPT_MASK); - - // From the next word and on is data - size_t spi_data_len; - pmt_t spi_data = pmt_make_u8vector(len - 6, 0); // skip rid+mbz+addr = 2 bytes - uint8_t *w_data = - (uint8_t *) pmt_u8vector_writable_elements(spi_data, spi_data_len); - - memcpy(w_data, d_payload + payload_offset + 8, spi_data_len); // skip first 2 words - - return pmt_list5(s_op_spi_write, enables, format, opt, spi_data); - } - - case OP_SPI_READ: - { - // Read the RID from the first word, the rest is mbz - pmt_t rid = pmt_from_long((subpkt >> CS_RID_SHIFT) & CS_RID_MASK); - - // Continue at the next word... - uint32_t word = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 4))); - pmt_t enables = pmt_from_long((word >> CS_SPIENABLES_SHIFT) & CS_SPIENABLES_MASK); - pmt_t format = pmt_from_long((word >> CS_SPIFORMAT_SHIFT) & CS_SPIFORMAT_MASK); - pmt_t opt = pmt_from_long((word >> CS_SPIOPT_SHIFT) & CS_SPIOPT_MASK); - - // The number of bytes is the only thing to read in the next word - word = usrp_to_host_u32(*((uint32_t *)(d_payload + payload_offset + 8))); - pmt_t n_bytes = pmt_from_long((word >> CS_SPINBYTES_SHIFT) & CS_SPINBYTES_MASK); - - return pmt_list6(s_op_spi_read, rid, enables, format, opt, n_bytes); - } - - case OP_DELAY: - { - pmt_t ticks = pmt_from_long((subpkt >> CS_DELAY_SHIFT) & CS_DELAY_MASK); - - return pmt_list2(s_op_delay, ticks); - } - - default: - return PMT_NIL; - - } -} - diff --git a/usrp/limbo/inband/usrp_inband_usb_packet.h b/usrp/limbo/inband/usrp_inband_usb_packet.h deleted file mode 100644 index 6f1a3feb3..000000000 --- a/usrp/limbo/inband/usrp_inband_usb_packet.h +++ /dev/null @@ -1,240 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef INCLUDED_USRP_INBAND_USB_PACKET_H_ -#define INCLUDED_USRP_INBAND_USB_PACKET_H_ - -#include <usrp_bytesex.h> -#include <mblock/mblock.h> -#include <pmt.h> -#include <iostream> - -#include <symbols_usrp_low_level_cs.h> - -static const int USB_PKT_SIZE = 512; // bytes -static const int MAX_PAYLOAD = USB_PKT_SIZE-2*sizeof(uint32_t); -static const int CONTROL_CHAN = 0x1f; - -class usrp_inband_usb_packet { - // - // keep raw packet in USRP-endian order - // - uint32_t d_word0; - uint32_t d_timestamp; - unsigned char d_payload[MAX_PAYLOAD]; - -public: - - enum opcodes { - OP_PING_FIXED = 0x00, - OP_PING_FIXED_REPLY = 0x01, - OP_WRITE_REG = 0x02, - OP_WRITE_REG_MASKED = 0x03, - OP_READ_REG = 0x04, - OP_READ_REG_REPLY = 0x05, - OP_I2C_WRITE = 0x06, - OP_I2C_READ = 0x07, - OP_I2C_READ_REPLY = 0x08, - OP_SPI_WRITE = 0x09, - OP_SPI_READ = 0x0a, - OP_SPI_READ_REPLY = 0x0b, - OP_DELAY = 0x0c - }; - - enum flags { - FL_OVERRUN = 0x80000000, - FL_UNDERRUN = 0x40000000, - FL_DROPPED = 0x20000000, - FL_START_OF_BURST = 0x10000000, - FL_END_OF_BURST = 0x08000000, - FL_CARRIER_SENSE = 0x04000000, - - FL_ALL_FLAGS = 0xfc000000 - }; - - static const int FL_OVERRUN_SHIFT = 31; - static const int FL_UNDERRUN_SHIFT = 30; - static const int FL_DROPPED_SHIFT = 29; - static const int FL_END_OF_BURST_SHIFT = 27; - static const int FL_START_OF_BURST_SHIFT = 28; - - static const int RSSI_MASK = 0x3f; - static const int RSSI_SHIFT = 21; - - static const int CHAN_MASK = 0x1f; - static const int CHAN_SHIFT = 16; - - static const int TAG_MASK = 0xf; - static const int TAG_SHIFT = 9; - - static const int PAYLOAD_LEN_MASK = 0x1ff; - static const int PAYLOAD_LEN_SHIFT = 0; - - // Fixed size for opcode and length fields - static const int CS_FIXED_LEN = 2; - - static const int CS_OPCODE_MASK = 0xff; - static const int CS_OPCODE_SHIFT = 24; - - static const int CS_LEN_MASK = 0xff; - static const int CS_LEN_SHIFT = 16; - - static const int CS_RID_MASK = 0x3f; - static const int CS_RID_SHIFT = 10; - - static const int CS_PING_LEN = 2; - static const int CS_PINGVAL_MASK = 0x3ff; - static const int CS_PINGVAL_SHIFT = 0; - - static const int CS_WRITEREG_LEN = 6; - static const int CS_WRITEREGMASKED_LEN = 10; - static const int CS_READREG_LEN = 2; - static const int CS_READREGREPLY_LEN = 6; - static const int CS_REGNUM_MASK = 0x3ff; - static const int CS_REGNUM_SHIFT = 0; - - static const int CS_DELAY_LEN = 2; - static const int CS_DELAY_MASK = 0xffff; - static const int CS_DELAY_SHIFT = 0; - - static const int CS_I2CADDR_MASK = 0x7f; - static const int CS_I2CADDR_SHIFT = 0; - - static const int CS_I2CREAD_LEN = 3; - static const int CS_I2CREADBYTES_MASK = 0x7f; - static const int CS_I2CREADBYTES_SHIFT = 24; - - static const int CS_SPIOPT_MASK = 0xffff; - static const int CS_SPIOPT_SHIFT = 0; - static const int CS_SPIFORMAT_MASK = 0xff; - static const int CS_SPIFORMAT_SHIFT = 16; - static const int CS_SPIENABLES_MASK = 0xff; - static const int CS_SPIENABLES_SHIFT = 24; - static const int CS_SPIREAD_LEN = 7; - static const int CS_SPINBYTES_MASK = 0xff; - static const int CS_SPINBYTES_SHIFT = 24; - -public: - - void set_timestamp(uint32_t timestamp){ - d_timestamp = host_to_usrp_u32(timestamp); - } - - void set_end_of_burst() { - uint32_t word0 = usrp_to_host_u32(d_word0); - word0 |= 1<<FL_END_OF_BURST_SHIFT; - d_word0 = host_to_usrp_u32(word0); - } - - void set_header(int flags, int chan, int tag, int payload_len){ - uint32_t word0 = ((flags & FL_ALL_FLAGS) - | ((chan & CHAN_MASK) << CHAN_SHIFT) - | ((tag & TAG_MASK) << TAG_SHIFT) - | ((payload_len & PAYLOAD_LEN_MASK) << PAYLOAD_LEN_SHIFT)); - d_word0 = host_to_usrp_u32(word0); - } - - void incr_header_len(int val) { - set_header(flags(), chan(), tag(), payload_len() + val); - } - - uint32_t timestamp() const { - return usrp_to_host_u32(d_timestamp); - } - - int rssi() const { - uint32_t word0 = usrp_to_host_u32(d_word0); - return (word0 >> RSSI_SHIFT) & RSSI_MASK; - } - - int chan() const { - uint32_t word0 = usrp_to_host_u32(d_word0); - return (word0 >> CHAN_SHIFT) & CHAN_MASK; - } - - int tag() const { - uint32_t word0 = usrp_to_host_u32(d_word0); - return (word0 >> TAG_SHIFT) & TAG_MASK; - } - - int payload_len() const { - uint32_t word0 = usrp_to_host_u32(d_word0); - return (word0 >> PAYLOAD_LEN_SHIFT) & PAYLOAD_LEN_MASK; - } - - int flags() const { - return usrp_to_host_u32(d_word0) & FL_ALL_FLAGS; - } - - int overrun() const { - return (usrp_to_host_u32(d_word0) & FL_OVERRUN) >> FL_OVERRUN_SHIFT; - } - - - int underrun() const { - return (usrp_to_host_u32(d_word0) & FL_UNDERRUN) >> FL_UNDERRUN_SHIFT; - } - - - int start_of_burst() const { - return (usrp_to_host_u32(d_word0) & FL_START_OF_BURST) >> FL_START_OF_BURST_SHIFT; - } - - int end_of_burst() const { - return (usrp_to_host_u32(d_word0) & FL_END_OF_BURST) >> FL_END_OF_BURST_SHIFT; - } - - int dropped() const { - return (usrp_to_host_u32(d_word0) & FL_DROPPED) >> FL_DROPPED_SHIFT; - } - - unsigned char *payload() { - return d_payload; - } - - static int max_payload() { - return MAX_PAYLOAD; - } - - static int max_pkt_size() { - return USB_PKT_SIZE; - } - - // C/S methods - bool align32(); - bool cs_ping(long rid, long ping_val); - bool cs_ping_reply(long rid, long ping_val); - bool cs_write_reg(long reg_num, long val); - bool cs_write_reg_masked(long reg_num, long val, long mask); - bool cs_read_reg(long rid, long reg_num); - bool cs_read_reg_reply(long rid, long reg_num, long reg_val); - bool cs_delay(long ticks); - bool cs_i2c_write(long i2c_addr, uint8_t *i2c_data, size_t data_len); - bool cs_i2c_read(long rid, long i2c_addr, long n_bytes); - bool cs_i2c_read_reply(long rid, long i2c_addr, uint8_t *i2c_data, long i2c_data_len); - bool cs_spi_write(long enables, long format, long opt_header_bytes, uint8_t *spi_data, long spi_data_len); - bool cs_spi_read(long rid, long enables, long format, long opt_header_bytes, long n_bytes); - bool cs_spi_read_reply(long rid, uint8_t *spi_data, long spi_data_len); - int cs_len(int payload_offset); - pmt_t read_subpacket(int payload_offset); -}; - -#endif diff --git a/usrp/limbo/inband/usrp_interface.mbh b/usrp/limbo/inband/usrp_interface.mbh deleted file mode 100644 index ad0f78b4e..000000000 --- a/usrp/limbo/inband/usrp_interface.mbh +++ /dev/null @@ -1,88 +0,0 @@ -;; -*- scheme -*- ; not really, but tells emacs how to format this -;; -;; Copyright 2007 Free Software Foundation, Inc. -;; -;; This file is part of GNU Radio -;; -;; GNU Radio is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. -;; -;; GNU Radio is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License along -;; with this program; if not, write to the Free Software Foundation, Inc., -;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -;; - -;; ---------------------------------------------------------------- -;; This is an mblock header file -;; -;; The format is very much a work-in-progress. -;; It'll be compiled to C++. -;; ---------------------------------------------------------------- - -;; ---------------------------------------------------------------- -;; usrp-interface-cs -;; -;; Handles interaction between the usrp_sever and the USB interface - -(define-protocol-class usrp-interface-cs - - (:outgoing - (cmd-usrp-open invocation-handle which-usrp) - (cmd-usrp-close invocation-handle) - (cmd-usrp-ntx-chan invocation-handle) - (cmd-usrp-nrx-chan invocation-handle) - (cmd-usrp-write invocation-handle channel data) - (cmd-usrp-start-reading invocation-handle channel) - ) - - (:incoming - (response-usrp-open invocation-handle status) - (response-usrp-close invocation-handle status) - (response-usrp-ntx-chan invocation-handle ntx-chan) - (response-usrp-nrx-chan invocation-handle nrx-chan) - (response-usrp-write invocation-handle status channel) - (response-usrp-read invocation-handle status data) - ) - ) - -;; ---------------------------------------------------------------- -;; usrp-tx-cs -;; -;; Handles interaction between the USB interface and TX interface - -(define-protocol-class usrp-tx-cs - - (:outgoing - (cmd-usrp-tx-write invocation-handle channel data tx-handle) - ) - - (:incoming - (response-usrp-tx-write invocation-handle status channel) - ) - ) - -;; ---------------------------------------------------------------- -;; usrp-rx-cs -;; -;; Handles interaction between the USB interface and RX interface - -(define-protocol-class usrp-rx-cs - - (:outgoing - (cmd-usrp-rx-start-reading invocation-handle rx-handle) - (cmd-usrp-rx-stop-reading invocation-handle) - ) - - (:incoming - (response-usrp-rx-read invocation-handle status data) - - ;; There is currently no response to a stop reading - ) - ) diff --git a/usrp/limbo/inband/usrp_rx.cc b/usrp/limbo/inband/usrp_rx.cc deleted file mode 100644 index fe9486cf6..000000000 --- a/usrp/limbo/inband/usrp_rx.cc +++ /dev/null @@ -1,184 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <usrp_rx.h> - -#include <usrp_standard.h> -#include <iostream> -#include <vector> -#include <usb.h> -#include <mblock/class_registry.h> -#include <usrp_inband_usb_packet.h> -#include <fpga_regs_common.h> -#include <stdio.h> - -#include <symbols_usrp_rx_cs.h> - -typedef usrp_inband_usb_packet transport_pkt; - -static const bool verbose = false; - -bool usrp_rx_stop; - -usrp_rx::usrp_rx(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(rt, instance_name, user_arg), - d_disk_write(false), - d_disk_write_pkt(false) // if true, writes full packet, else just the payload -{ - d_cs = define_port("cs", "usrp-rx-cs", true, mb_port::EXTERNAL); - - if(d_disk_write) { - d_ofile0.open("rx_data_chan0.dat",std::ios::binary|std::ios::out); - d_ofile1.open("rx_data_chan1.dat",std::ios::binary|std::ios::out); - d_cs_ofile.open("rx_cs.dat",std::ios::binary|std::ios::out); - } - - usrp_rx_stop = false; - -} - -usrp_rx::~usrp_rx() -{ - if(d_disk_write) { - d_ofile0.close(); - d_ofile1.close(); - d_cs_ofile.close(); - } -} - -void -usrp_rx::initial_transition() -{ - -} - -/*! - * \brief Handles incoming signals to to the m-block, wihch should only ever be - * a single message: cmd-usrrp-rx-start-reading. There is no signal to stop - * reading as the m-block goes in to a forever loop to read inband packets from - * the bus. - */ -void -usrp_rx::handle_message(mb_message_sptr msg) -{ - pmt_t event = msg->signal(); - pmt_t port_id = msg->port_id(); - pmt_t data = msg->data(); - - // Theoretically only have 1 message to ever expect, but - // want to make sure its at least what we want - if(pmt_eq(port_id, d_cs->port_symbol())) { - - if(pmt_eqv(event, s_cmd_usrp_rx_start_reading)) - read_and_respond(data); - } -} - -/*! - * \brief Performs the actual reading of data from the USB bus, called by - * handle_message() when a cmd-usrp-rx-start-reading signal is received. - * - * The method enters a forever loop where it continues to read data from the bus - * and generate read responses to the higher layer. Currently, shared memory is - * used to exit this loop. - * - * The \p data parameter is a PMT list which contains only a single element, an - * invocation handle which will be returned with all read respones. - */ -void -usrp_rx::read_and_respond(pmt_t data) -{ - size_t ignore; - bool underrun; - unsigned int n_read; - unsigned int pkt_size = sizeof(transport_pkt); - - pmt_t invocation_handle = pmt_nth(0, data); - - // Need the handle to the RX port to send responses, this is passed - // by the USRP interface m-block - pmt_t handle = pmt_nth(1, data); - d_urx = - boost::any_cast<usrp_standard_rx_sptr>(pmt_any_ref(handle)); - - if(verbose) - std::cout << "[usrp_rx] Waiting for packets..\n"; - - // Read by 512 which is packet size and send them back up - while(!usrp_rx_stop) { - - pmt_t v_pkt = pmt_make_u8vector(pkt_size, 0); - transport_pkt *pkt = - (transport_pkt *) pmt_u8vector_writable_elements(v_pkt, ignore); - - n_read = d_urx->read(pkt, pkt_size, &underrun); - - if(n_read != pkt_size) { - std::cerr << "[usrp_rx] Error reading packet, shutting down\n"; - d_cs->send(s_response_usrp_rx_read, - pmt_list3(PMT_NIL, PMT_F, PMT_NIL)); - return; - } - - if(underrun && verbose && 0) - std::cout << "[usrp_rx] Underrun\n"; - - d_cs->send(s_response_usrp_rx_read, - pmt_list3(PMT_NIL, PMT_T, v_pkt)); - if(verbose && 0) - std::cout << "[usrp_rx] Read 1 packet\n"; - - if(d_disk_write) { - if(pkt->chan() == CONTROL_CHAN) - d_cs_ofile.write((const char *)pkt, transport_pkt::max_pkt_size()); - else { - if(d_disk_write_pkt) { - if(pkt->chan() == 0) - d_ofile0.write((const char *)pkt, transport_pkt::max_pkt_size()); - else if(pkt->chan() == 1) - d_ofile1.write((const char *)pkt, transport_pkt::max_pkt_size()); - } else { - if(pkt->chan() == 0) - d_ofile0.write((const char *)pkt->payload(), transport_pkt::max_payload()); - else if(pkt->chan() == 1) - d_ofile1.write((const char *)pkt->payload(), transport_pkt::max_payload()); - } - } - - d_cs_ofile.flush(); - d_ofile0.flush(); - d_ofile1.flush(); - } - } - - usrp_rx_stop = false; - - if(verbose) { - std::cout << "[USRP_RX] Stopping...\n"; - fflush(stdout); - } -} - -REGISTER_MBLOCK_CLASS(usrp_rx); diff --git a/usrp/limbo/inband/usrp_rx.h b/usrp/limbo/inband/usrp_rx.h deleted file mode 100644 index 1006235bf..000000000 --- a/usrp/limbo/inband/usrp_rx.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef INCLUDED_USRP_RX_H -#define INCLUDED_USRP_RX_H - -#include <mblock/mblock.h> -#include <fstream> -#include "usrp_standard.h" - -extern bool usrp_rx_stop; // used to communicate a 'stop' to the RX stub - -/*! - * \brief Implements the low level usb interface to the USRP - */ -class usrp_rx : public mb_mblock -{ - mb_port_sptr d_cs; - usrp_standard_rx_sptr d_urx; - - bool d_disk_write; - bool d_disk_write_pkt; - std::ofstream d_ofile0; - std::ofstream d_ofile1; - std::ofstream d_cs_ofile; - - public: - usrp_rx(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg); - ~usrp_rx(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - private: - void read_and_respond(pmt_t data); - void read_data(); - -}; - - -#endif /* INCLUDED_USRP_RX_H */ - diff --git a/usrp/limbo/inband/usrp_rx_stub.cc b/usrp/limbo/inband/usrp_rx_stub.cc deleted file mode 100644 index e5c454d24..000000000 --- a/usrp/limbo/inband/usrp_rx_stub.cc +++ /dev/null @@ -1,227 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <usrp_rx_stub.h> - -#include <iostream> -#include <vector> -#include <usb.h> -#include <mblock/class_registry.h> -#include <usrp_inband_usb_packet.h> -#include <fpga_regs_common.h> -#include "usrp_standard.h" -#include <stdio.h> -#include <string.h> -#include <ui_nco.h> -#include <fstream> - -#include <symbols_usrp_rx_cs.h> - -typedef usrp_inband_usb_packet transport_pkt; - -static const bool verbose = false; - -bool usrp_rx_stop_stub; - -// Used for the fake control packet response code to send the responses back up -// the RX. The TX stub dumps responses in to this queue. -std::queue<pmt_t> d_cs_queue; - -usrp_rx_stub::usrp_rx_stub(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(rt, instance_name, user_arg), - d_samples_per_frame((long)(126)), - d_decim_rx(128), - d_amplitude(16384), - d_disk_write(false) -{ - - // Information about the rates are passed all the way from the app in the form - // of a dictionary. We use this to read the RX decimation rate and compute - // the approximate number of MS/s as a form of flow control for the stub. - pmt_t usrp_dict = user_arg; - - if (pmt_is_dict(usrp_dict)) { - // Read the RX decimation rate - if(pmt_t decim_rx = pmt_dict_ref(usrp_dict, - pmt_intern("decim-rx"), - PMT_NIL)) { - if(!pmt_eqv(decim_rx, PMT_NIL)) - d_decim_rx = pmt_to_long(decim_rx); - } - } - - d_cs = define_port("cs", "usrp-rx-cs", true, mb_port::EXTERNAL); - - // initialize NCO - double freq = 100e3; - int interp = 32; // 32 -> 4MS/s - double sample_rate = 64e6 / interp; - d_nco.set_freq(2*M_PI * freq/sample_rate); - - //d_disk_write = true; - - if(d_disk_write) - d_ofile.open("raw_rx.dat",std::ios::binary|std::ios::out); - - usrp_rx_stop_stub = false; -} - -usrp_rx_stub::~usrp_rx_stub() -{ - if(d_disk_write) - d_ofile.close(); -} - -void -usrp_rx_stub::initial_transition() -{ -} - -void -usrp_rx_stub::handle_message(mb_message_sptr msg) -{ - pmt_t event = msg->signal(); - pmt_t port_id = msg->port_id(); - pmt_t data = msg->data(); - - if (pmt_eq(msg->signal(), s_timeout) - && !pmt_eq(msg->data(), s_done)) { - - if(!usrp_rx_stop_stub) - read_and_respond(); - else { // requested to stop - cancel_timeout(msg->metadata()); - usrp_rx_stop_stub=false; - if(verbose) - std::cout << "[USRP_RX_STUB] Stopping RX stub\n"; - } - - } - - // Theoretically only have 1 message to ever expect, but - // want to make sure its at least what we want - if(pmt_eq(port_id, d_cs->port_symbol()) - && pmt_eqv(event, s_cmd_usrp_rx_start_reading)) { - - if(verbose) - std::cout << "[USRP_RX_STUB] Starting with decim @ " - << d_decim_rx << std::endl; - - start_packet_timer(); - } -} - -// Setup a periodic timer which will drive packet generation -void -usrp_rx_stub::start_packet_timer() -{ - d_t0 = mb_time::time(); // current time - - // Calculate the inter-packet arrival time. - double samples_per_sec = (64.0/(double)d_decim_rx)*1000000.0; - double frames_per_sec = samples_per_sec / (double)d_samples_per_frame; - double frame_rate = 1.0 / frames_per_sec; - - if(verbose) { - std::cout << "[USRP_RX_STUB] Scheduling periodic packet generator\n"; - std::cout << "\tsamples_per_sec: " << samples_per_sec << std::endl; - std::cout << "\tframes_per_sec: " << frames_per_sec << std::endl; - std::cout << "\tframe_rate: " << frame_rate << std::endl; - } - - schedule_periodic_timeout(d_t0 + frame_rate, mb_time(frame_rate), PMT_T); -} - -void -usrp_rx_stub::read_and_respond() -{ - - long nsamples_this_frame = d_samples_per_frame; - - size_t nshorts = 2 * nsamples_this_frame; // 16-bit I & Q - long channel = 0; - long n_bytes = nshorts*2; - pmt_t uvec = pmt_make_s16vector(nshorts, 0); - size_t ignore; - int16_t *samples = pmt_s16vector_writable_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(); - } - } - - if(d_disk_write) - d_ofile.write((const char *)samples, n_bytes); - - pmt_t v_pkt = pmt_make_u8vector(sizeof(transport_pkt), 0); - transport_pkt *pkt = - (transport_pkt *) pmt_u8vector_writable_elements(v_pkt, ignore); - - pkt->set_header(0, channel, 0, n_bytes); - pkt->set_timestamp(0xffffffff); - memcpy(pkt->payload(), samples, n_bytes); - - d_cs->send(s_response_usrp_rx_read, pmt_list3(PMT_NIL, PMT_T, v_pkt)); - - // Now lets check the shared CS queue between the TX and RX stub. Each - // element in a queue is a list where the first element is an invocation - // handle and the second element is a PMT u8 vect representation of the - // CS packet response which can just be passed transparently. - while(!d_cs_queue.empty()) { - - pmt_t cs_pkt = d_cs_queue.front(); - d_cs_queue.pop(); - - pmt_t invocation_handle = pmt_nth(0, cs_pkt); - pmt_t v_pkt = pmt_nth(1, cs_pkt); - - d_cs->send(s_response_usrp_rx_read, - pmt_list3(invocation_handle, - PMT_T, - v_pkt)); // Take the front CS pkt - - - if(verbose) - std::cout << "[USRP_RX_STUB] Received CS response from TX stub\n"; - } - -} - -REGISTER_MBLOCK_CLASS(usrp_rx_stub); diff --git a/usrp/limbo/inband/usrp_rx_stub.h b/usrp/limbo/inband/usrp_rx_stub.h deleted file mode 100644 index 238b4568f..000000000 --- a/usrp/limbo/inband/usrp_rx_stub.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef INCLUDED_USRP_RX_STUB_H -#define INCLUDED_USRP_RX_STUB_H - -#include <mblock/mblock.h> -#include <vector> -#include "usrp_standard.h" -#include <ui_nco.h> -#include <fstream> -#include <queue> -#include <usrp_inband_usb_packet.h> - -typedef usrp_inband_usb_packet transport_pkt; - -extern bool usrp_rx_stop_stub; // used to communicate a 'stop' to the RX stub -extern std::queue<pmt_t> d_cs_queue; - -static pmt_t s_timeout = pmt_intern("%timeout"); -static pmt_t s_done = pmt_intern("done"); - -/*! - * \brief Implements the low level usb interface to the USRP - */ -class usrp_rx_stub : public mb_mblock -{ - public: - - mb_port_sptr d_cs; - usrp_standard_rx* d_urx; - - long d_samples_per_frame; - long d_decim_rx; - - mb_time d_t0; - double d_delta_t; - - // for generating sine wave output - ui_nco<float,float> d_nco; - double d_amplitude; - - bool d_disk_write; - - std::ofstream d_ofile; - - public: - usrp_rx_stub(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg); - ~usrp_rx_stub(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - private: - void read_and_respond(); - void read_data(); - void start_packet_timer(); - -}; - - -#endif /* INCLUDED_USRP_RX_H */ - diff --git a/usrp/limbo/inband/usrp_server.cc b/usrp/limbo/inband/usrp_server.cc deleted file mode 100644 index 4f5f396b4..000000000 --- a/usrp/limbo/inband/usrp_server.cc +++ /dev/null @@ -1,1861 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <usrp_server.h> -#include <iostream> -#include <usrp_inband_usb_packet.h> -#include <mblock/class_registry.h> -#include <vector> -#include <usrp_usb_interface.h> -#include <string.h> -#include <fpga_regs_common.h> -#include <fpga_regs_standard.h> - -#include <symbols_usrp_server_cs.h> -#include <symbols_usrp_channel.h> -#include <symbols_usrp_tx.h> -#include <symbols_usrp_rx.h> -#include <symbols_usrp_low_level_cs.h> -#include <symbols_usrp_interface_cs.h> - -static pmt_t s_shutdown = pmt_intern("%shutdown"); - -typedef usrp_inband_usb_packet transport_pkt; // makes conversion to gigabit easy - -const static bool verbose = false; - -static std::string -str(long x) -{ - std::ostringstream s; - s << x; - return s.str(); -} - -usrp_server::usrp_server(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(rt, instance_name, user_arg), - d_fpga_debug(false), - d_interp_tx(128), // these should match the lower level defaults (rx also) - d_decim_rx(128), - d_fake_rx(false) -{ - if(verbose) - std::cout << "[USRP_SERVER] Initializing...\n"; - - // Dictionary for arguments to all of the components - d_usrp_dict = user_arg; - - if (pmt_is_dict(d_usrp_dict)) { - - if(pmt_t fpga_debug = pmt_dict_ref(d_usrp_dict, - pmt_intern("fpga-debug"), - PMT_NIL)) { - if(pmt_eqv(fpga_debug, PMT_T)) - d_fpga_debug=true; - } - - // Read the TX interpolations - if(pmt_t interp_tx = pmt_dict_ref(d_usrp_dict, - pmt_intern("interp-tx"), - PMT_NIL)) { - if(!pmt_eqv(interp_tx, PMT_NIL)) - d_interp_tx = pmt_to_long(interp_tx); - } - - // Read the RX decimation rate - if(pmt_t decim_rx = pmt_dict_ref(d_usrp_dict, - pmt_intern("decim-rx"), - PMT_NIL)) { - if(!pmt_eqv(decim_rx, PMT_NIL)) - d_decim_rx = pmt_to_long(decim_rx); - } - } - - // control & status port - d_cs = define_port("cs", "usrp-server-cs", true, mb_port::EXTERNAL); - d_cs_usrp = define_port("cs_usrp", "usrp-interface-cs", false, mb_port::INTERNAL); - - // ports - // - // (if/when we do replicated ports, these will be replaced by a - // single replicated port) - for(int port=0; port < N_PORTS; port++) { - - d_tx.push_back(define_port("tx"+str(port), - "usrp-tx", - true, - mb_port::EXTERNAL)); - - d_rx.push_back(define_port("rx"+str(port), - "usrp-rx", - true, - mb_port::EXTERNAL)); - } - - define_component("usrp", "usrp_usb_interface", d_usrp_dict); - connect("self", "cs_usrp", "usrp", "cs"); - - d_defer=false; - d_opened=false; - - // FIXME: needs to be returned from open, if we want to use this - d_nrx_chan = 2; - d_ntx_chan = 2; - - // Initialize capacity on each channel to 0 and to no owner - // Also initialize the USRP standard tx/rx pointers to NULL - for(int chan=0; chan < d_ntx_chan; chan++) - d_chaninfo_tx.push_back(channel_info()); - - for(int chan=0; chan < d_nrx_chan; chan++) - d_chaninfo_rx.push_back(channel_info()); - - d_rx_chan_mask = 0; - - for(int i=0; i < D_MAX_RID; i++) - d_rids.push_back(rid_info()); - - //d_fake_rx=true; -} - -/*! - * \brief resets the assigned capacity and owners of each RX and TX channel from - * allocations. - */ -void -usrp_server::reset_channels() -{ - - for(int chan=0; chan < d_ntx_chan; chan++) { - d_chaninfo_tx[chan].assigned_capacity = 0; - d_chaninfo_tx[chan].owner = PMT_NIL; - } - - for(int chan=0; chan < d_nrx_chan; chan++) { - d_chaninfo_rx[chan].assigned_capacity = 0; - d_chaninfo_rx[chan].owner = PMT_NIL; - } - - d_rx_chan_mask = 0; -} - -usrp_server::~usrp_server() -{ -} - - -void -usrp_server::initial_transition() -{ - // the initial transition -} - -/*! - * \brief Reads all incoming messages to USRP server from the TX, RX, and the CS - * ports. This drives the state of USRP server and dispatches based on the - * message. - */ -void -usrp_server::handle_message(mb_message_sptr msg) -{ - pmt_t event = msg->signal(); // the "name" of the message - pmt_t port_id = msg->port_id(); // which port it came in on - pmt_t data = msg->data(); - pmt_t invocation_handle; - pmt_t metadata = msg->metadata(); - pmt_t status; - - long port; - - if (pmt_eq(event, s_shutdown)) // ignore (for now) - return; - - invocation_handle = pmt_nth(0, data); - - if (0){ - std::cout << "[USRP_SERVER] event: " << event << std::endl; - std::cout << "[USRP_SERVER] port_id: " << port_id << std::endl; - } - - // It would be nice if this were all table driven, and we could compute our - // state transition as f(current_state, port_id, signal) - - // A message from the USRP CS, which should *only* be responses - // - // It is important that this set come before checking messages of any other - // components. This is since we always want to listen to the low level USRP - // server, even if we aren't initialized we are waiting for responses to - // become initialized. Likewise, after the usrp_server is "closed", we still - // want to pass responses back from the low level. - - //---------------- USRP RESPONSE ---------------// - if (pmt_eq(port_id, d_cs_usrp->port_symbol())) { - - //-------------- USRP OPEN ------------------// - if(pmt_eq(event, s_response_usrp_open)) { - // pass the response back over the regular CS port - pmt_t status = pmt_nth(1, data); - d_cs->send(s_response_open, pmt_list2(invocation_handle, status)); - - //reset_all_registers(); - //initialize_registers(); - - if(pmt_eqv(status,PMT_T)) { - d_opened = true; - d_defer = false; - recall_defer_queue(); - } - - return; - } - //------------- USRP CLOSE -------------------// - else if (pmt_eq(event, s_response_usrp_close)) { - pmt_t status = pmt_nth(1, data); - d_cs->send(s_response_close, pmt_list2(invocation_handle, status)); - - if(pmt_eqv(status,PMT_T)) { - d_opened = false; - d_defer = false; - reset_channels(); - recall_defer_queue(); - } - - return; - } - //--------------- USRP WRITE --------------// - else if (pmt_eq(event, s_response_usrp_write)) { - - pmt_t status = pmt_nth(1, data); - long channel = pmt_to_long(pmt_nth(2, data)); - long port; - - // Do not report back responses if they were generated from a - // command packet - if(channel == CONTROL_CHAN) - return; - - // Find the port through the owner of the channel - if((port = tx_port_index(d_chaninfo_tx[channel].owner)) !=-1 ){ - d_tx[port]->send(s_response_xmit_raw_frame, - pmt_list2(invocation_handle, status)); - return; - } - } - //--------------- USRP READ ---------------// - else if (pmt_eq(event, s_response_usrp_read)) { - - pmt_t status = pmt_nth(1, data); - - if(!pmt_eqv(status, PMT_T)) { - std::cerr << "[USRP_SERVER] Error receiving packet\n"; - return; - } - else { - handle_response_usrp_read(data); - return; - } - } - - goto unhandled; - } - - // Checking for defer on all other messages - if(d_defer) { - if (verbose) - std::cout << "[USRP_SERVER] Received msg while deferring (" - << msg->signal() << ")\n"; - d_defer_queue.push(msg); - return; - } - - //--------- CONTROL / STATUS ------------// - if (pmt_eq(port_id, d_cs->port_symbol())){ - - //----------- OPEN -----------// - if (pmt_eq(event, s_cmd_open)){ - - // Reject if already open - if(d_opened) { - d_cs->send(s_response_open, pmt_list2(invocation_handle, s_err_usrp_already_opened)); - return; - } - - // the parameters are the same to the low level interface, so we just pass 'data' along - d_cs_usrp->send(s_cmd_usrp_open, data); - - d_defer = true; - - return; - } - //---------- CLOSE -----------// - else if (pmt_eq(event, s_cmd_close)){ - - if(!d_opened) { - d_cs->send(s_response_close, pmt_list2(invocation_handle, s_err_usrp_already_closed)); - return; - } - - d_defer = true; - d_cs_usrp->send(s_cmd_usrp_close, pmt_list1(invocation_handle)); - - return; - } - //---------- MAX CAPACITY ----------// - else if (pmt_eq(event, s_cmd_max_capacity)) { - - if(!d_opened) { - d_cs->send(s_response_max_capacity, - pmt_list3(invocation_handle, s_err_usrp_not_opened, pmt_from_long(0))); - return; - } - - d_cs->send(s_response_max_capacity, - pmt_list3(invocation_handle, - PMT_T, - pmt_from_long(max_capacity()))); - return; - } - //---------- NTX CHAN --------------// - else if (pmt_eq(event, s_cmd_ntx_chan)) { - - if(!d_opened) { - d_cs->send(s_response_ntx_chan, - pmt_list3(invocation_handle, s_err_usrp_not_opened, pmt_from_long(0))); - return; - } - - d_cs->send(s_response_ntx_chan, - pmt_list3(invocation_handle, - PMT_T, - pmt_from_long(d_ntx_chan))); - return; - } - //---------- NRX CHAN -----------// - else if (pmt_eq(event, s_cmd_nrx_chan)) { - - if(!d_opened) { - d_cs->send(s_response_nrx_chan, - pmt_list3(invocation_handle, s_err_usrp_not_opened, pmt_from_long(0))); - return; - } - - d_cs->send(s_response_nrx_chan, - pmt_list3(invocation_handle, - PMT_T, - pmt_from_long(d_nrx_chan))); - return; - } - //--------- ALLOCATION? -----------// - else if (pmt_eq(event, s_cmd_current_capacity_allocation)) { - - if(!d_opened) { - d_cs->send(s_response_current_capacity_allocation, - pmt_list3(invocation_handle, - s_err_usrp_not_opened, - pmt_from_long(0))); - return; - } - - d_cs->send(s_response_current_capacity_allocation, - pmt_list3(invocation_handle, - PMT_T, - pmt_from_long(current_capacity_allocation()))); - return; - } - goto unhandled; - } - - //-------------- TX ---------------// - if ((port = tx_port_index(port_id)) != -1) { - - //------------ ALLOCATE (TX) ----------------// - if (pmt_eq(event, s_cmd_allocate_channel)){ - - if(!d_opened) { - d_tx[port]->send(s_response_allocate_channel, - pmt_list3(invocation_handle, - s_err_usrp_not_opened, - pmt_from_long(0))); - return; - } - - handle_cmd_allocate_channel(d_tx[port], d_chaninfo_tx, data); - return; - } - - //----------- DEALLOCATE (TX) ---------------// - if (pmt_eq(event, s_cmd_deallocate_channel)) { - - if(!d_opened) { - d_tx[port]->send(s_response_deallocate_channel, - pmt_list3(invocation_handle, - s_err_usrp_not_opened, - pmt_from_long(0))); - return; - } - - handle_cmd_deallocate_channel(d_tx[port], d_chaninfo_tx, data); - return; - } - - //-------------- XMIT RAW FRAME -----------------/ - if (pmt_eq(event, s_cmd_xmit_raw_frame)){ - - if(!d_opened) { - d_tx[port]->send(s_response_xmit_raw_frame, - pmt_list2(invocation_handle, s_err_usrp_not_opened)); - return; - } - - handle_cmd_xmit_raw_frame(d_tx[port], d_chaninfo_tx, data); - return; - } - - //-------------- CONTROL PACKET -----------------/ - if (pmt_eq(event, s_cmd_to_control_channel)) { - - if(!d_opened) { - d_tx[port]->send(s_response_xmit_raw_frame, - pmt_list2(invocation_handle, s_err_usrp_not_opened)); - return; - } - - handle_cmd_to_control_channel(d_tx[port], d_chaninfo_tx, data); - return; - - } - - goto unhandled; - } - - //-------------- RX ---------------// - if ((port = rx_port_index(port_id)) != -1) { - - //------------ ALLOCATE (RX) ----------------// - if (pmt_eq(event, s_cmd_allocate_channel)) { - - if(!d_opened) { - d_rx[port]->send(s_response_allocate_channel, - pmt_list3(invocation_handle, - s_err_usrp_not_opened, - pmt_from_long(0))); - return; - } - - handle_cmd_allocate_channel(d_rx[port], d_chaninfo_rx, data); - return; - } - - //----------- DEALLOCATE (RX) ---------------// - if (pmt_eq(event, s_cmd_deallocate_channel)) { - - if(!d_opened) { - d_rx[port]->send(s_response_deallocate_channel, - pmt_list3(invocation_handle, - s_err_usrp_not_opened, - pmt_from_long(0))); - return; - } - - handle_cmd_deallocate_channel(d_rx[port], d_chaninfo_rx, data); - return; - } - - //-------------- START RECV ----------------// - if (pmt_eq(event, s_cmd_start_recv_raw_samples)) { - - if(!d_opened) { - d_rx[port]->send(s_response_recv_raw_samples, - pmt_list2(invocation_handle, s_err_usrp_not_opened)); - return; - } - - handle_cmd_start_recv_raw_samples(d_rx[port], d_chaninfo_rx, data); - return; - } - - //-------------- STOP RECV ----------------// - if (pmt_eq(event, s_cmd_stop_recv_raw_samples)) { - - if(!d_opened) - return; - - // FIX ME : no response for stopping? even if error? (permissions) - handle_cmd_stop_recv_raw_samples(d_rx[port], d_chaninfo_rx, data); - - return; - } - - goto unhandled; - } - - unhandled: - std::cout << "[USRP_SERVER] unhandled msg: " << msg << std::endl; -} - -/*! - * \brief Takes a port_symbol() as parameter \p port_id and is used to determine - * if the port is a TX port, or to find an index in the d_tx vector which stores - * the port. - * - * \returns -1 if \p port_id is not in the d_tx vector (i.e., it's not a TX - * port), otherwise returns an index in the d_tx vector which stores the port. - */ -int usrp_server::tx_port_index(pmt_t port_id) { - - for(int i=0; i < (int) d_tx.size(); i++) - if(pmt_eq(d_tx[i]->port_symbol(), port_id)) - return i; - - return -1; -} - -/*! - * \brief Takes a port_symbol() as parameter \p port_id and is used to determine - * if the port is an RX port, or to find an index in the d_rx vector which - * stores the port. - * - * \returns -1 if \p port_id is not in the d_rx vector (i.e., it's not an RX - * port), otherwise returns an index in the d_rx vector which stores the port. - */ -int usrp_server::rx_port_index(pmt_t port_id) { - - for(int i=0; i < (int) d_rx.size(); i++) - if(pmt_eq(d_rx[i]->port_symbol(), port_id)) - return i; - - return -1; -} - -/*! - * \brief Determines the current total capacity allocated by all RX and TX - * channels. - * - * \returns the total allocated capacity - */ -long usrp_server::current_capacity_allocation() { - long capacity = 0; - - for(int chan=0; chan < d_ntx_chan; chan++) - capacity += d_chaninfo_tx[chan].assigned_capacity; - - for(int chan=0; chan < d_nrx_chan; chan++) - capacity += d_chaninfo_rx[chan].assigned_capacity; - - return capacity; -} - - -/*! - * \brief Called by the handle_message() method if the incoming message to - * usrp_server is to allocate a channel (cmd-allocate-channel). The method - * checks if the requested capacity exists and if so it will reserve it for the - * caller on the channel that is returned via a response-allocate-channel - * signal. - */ -void -usrp_server::handle_cmd_allocate_channel( - mb_port_sptr port, - std::vector<struct channel_info> &chan_info, - pmt_t data) -{ - pmt_t invocation_handle = pmt_nth(0, data); - long rqstd_capacity = pmt_to_long(pmt_nth(1, data)); - long chan; - - // Check capacity exists - if((D_USB_CAPACITY - current_capacity_allocation()) < rqstd_capacity) { - - // no capacity available - port->send(s_response_allocate_channel, - pmt_list3(invocation_handle, - s_err_requested_capacity_unavailable, - PMT_NIL)); - return; - } - - // Find a free channel, assign the capacity and respond - for(chan=0; chan < (long)chan_info.size(); chan++) { - - if(verbose) - std::cout << "[USRP_SERVER] Checking chan: " << chan - << " owner " << chan_info[chan].owner - << " size " << chan_info.size() - << std::endl; - - if(chan_info[chan].owner == PMT_NIL) { - - chan_info[chan].owner = port->port_symbol(); - chan_info[chan].assigned_capacity = rqstd_capacity; - - port->send(s_response_allocate_channel, - pmt_list3(invocation_handle, - PMT_T, - pmt_from_long(chan))); - - if(verbose) - std::cout << "[USRP_SERVER] Assigning channel: " << chan - << " to " << chan_info[chan].owner - << std::endl; - return; - } - - } - - if (verbose) - std::cout << "[USRP_SERVER] Couldnt find a TX chan\n"; - - // no free TX chan found - port->send(s_response_allocate_channel, - pmt_list3(invocation_handle, - s_err_channel_unavailable, - PMT_NIL)); - return; -} - -/*! - * \brief Called by the handle_message() method if the incoming message to - * usrp_server is to deallocate a channel (cmd-deallocate-channel). The method - * ensures that the sender of the signal owns the channel and that the channel - * number is valid. A response-deallocate-channel signal is sent back with the - * result of the deallocation. - */ -void -usrp_server::handle_cmd_deallocate_channel( - mb_port_sptr port, - std::vector<struct channel_info> &chan_info, - pmt_t data) -{ - - pmt_t invocation_handle = pmt_nth(0, data); - long channel = pmt_to_long(pmt_nth(1, data)); - - // Ensure the channel is valid and the caller owns the port - if(!check_valid(port, channel, chan_info, - pmt_list2(s_response_deallocate_channel, invocation_handle))) - return; - - chan_info[channel].assigned_capacity = 0; - chan_info[channel].owner = PMT_NIL; - - port->send(s_response_deallocate_channel, - pmt_list2(invocation_handle, - PMT_T)); - return; -} - -/*! - * \brief Called by the handle_message() method if the incoming message to - * usrp_server is to transmit a frame (cmd-xmit-raw-frame). The method - * allocates enough memory to support a burst of packets which contain the frame - * over the bus of the frame, sets the packet headers, and sends a signal to the - * lower block for the data (packets) to be written to the bus. - * - * The \p port the command was sent on and the channel info (\p chan_info) of - * the channel the frame is to be transmitted on are passed to ensure that the - * caller owns the channel. - * - * The \p data parameter is in the format of a cmd-xmit-raw-frame signal. - * - * The properties - */ -void usrp_server::handle_cmd_xmit_raw_frame( - mb_port_sptr port, - std::vector<struct channel_info> &chan_info, - pmt_t data) -{ - size_t n_bytes, psize; - long max_payload_len = transport_pkt::max_payload(); - - 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), n_bytes); - long timestamp = pmt_to_long(pmt_nth(3, data)); - pmt_t properties = pmt_nth(4, data); - - // Ensure the channel is valid and the caller owns the port - if(!check_valid(port, channel, chan_info, - pmt_list2(s_response_xmit_raw_frame, invocation_handle))) - return; - - // Read information from the properties of the packet - bool carrier_sense = false; - if(pmt_is_dict(properties)) { - - // Check if carrier sense is enabled for the frame - if(pmt_t p_carrier_sense = pmt_dict_ref(properties, - pmt_intern("carrier-sense"), - PMT_NIL)) { - if(pmt_eqv(p_carrier_sense, PMT_T)) - carrier_sense = true; - } - } - - - // Determine the number of packets to allocate contiguous memory for - // bursting over the USB and get a pointer to the memory to be used in - // building the packets - long n_packets = - static_cast<long>(std::ceil(n_bytes / (double)max_payload_len)); - - pmt_t v_packets = pmt_make_u8vector(sizeof(transport_pkt) * n_packets, 0); - - transport_pkt *pkts = - (transport_pkt *) pmt_u8vector_writable_elements(v_packets, psize); - - for(int n=0; n < n_packets; n++) { - - long payload_len = - std::min((long)(n_bytes-(n*max_payload_len)), (long)max_payload_len); - - if(n == 0) { // first packet gets start of burst flag and timestamp - - if(carrier_sense) - pkts[n].set_header(pkts[n].FL_START_OF_BURST - | pkts[n].FL_CARRIER_SENSE, - channel, 0, payload_len); - else - pkts[n].set_header(pkts[n].FL_START_OF_BURST, channel, 0, payload_len); - - pkts[n].set_timestamp(timestamp); - - } else { - pkts[n].set_header(0, channel, 0, payload_len); - pkts[n].set_timestamp(0xffffffff); - } - - memcpy(pkts[n].payload(), - (uint8_t *)samples+(max_payload_len * n), - payload_len); - - } - - - pkts[n_packets-1].set_end_of_burst(); // set the last packet's end of burst - - if (verbose && 0) - std::cout << "[USRP_SERVER] Received raw frame invocation: " - << invocation_handle << std::endl; - - // The actual response to the write will be generated by a - // s_response_usrp_write since we cannot determine whether to transmit was - // successful until we hear from the lower layers. - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(invocation_handle, - pmt_from_long(channel), - v_packets)); - - return; -} - -/*! - * \brief Called by the handle_message() method to parse incoming control/status - * signals (cmd-to-control-channel). - * - * The \p port the command was sent on and the channel info (\p chan_info) of - * the channel are passed to ensure that the caller owns the channel. - * - * The \p data parameter is in the format of a PMT list, where each element - * follows the format of a control/status signal (i.e. op-ping-fixed). - * - * The method will parse all of the C/S commands included in \p data and place - * the commands in to a lower level packet sent to the control channel. The - * method will pack as many commands as possible in t oa single packet, and once - * it is fill generate as many lower level packets as needed. - * - * Anything that needs to be returned to the sender of the signal (i.e. the - * value of a register) will be generated by the parse_control_pkt() method as - * the responses to the commands are read back from the USRP. - */ -void usrp_server::handle_cmd_to_control_channel( - mb_port_sptr port, - std::vector<struct channel_info> &chan_info, - pmt_t data) -{ - - pmt_t invocation_handle = pmt_nth(0, data); - pmt_t subpackets = pmt_nth(1, data); - - long n_subpkts = pmt_length(subpackets); - long curr_subpkt = 0; - - size_t psize; - long payload_len = 0; - long channel = CONTROL_CHAN; - - if(verbose) - std::cout << "[USRP_SERVER] Handling " << n_subpkts << " commands\n"; - - // The design of the following code is optimized for simplicity, not - // performance. To performance optimize this code, the total size in bytes - // needed for all of the CS packets is needed to allocate contiguous memory - // which contains the USB packets for bursting over the bus. However to do - // this the packets subpackets would need to be parsed twice and their sizes - // would need to be determined. - // - // The approach taken is to keep parsing the subpackets and putting them in to - // USB packets. Once the USB packet is full, a write is sent for it and - // another packet is created. - // - // The subpacket creation methods will return false if the subpacket will not - // fit in to the current USB packet. In these cases a new USB packet is - // created and the old is sent. - - new_packet: - // This code needs to become "smart" and only make a new packet when full - pmt_t v_packet = pmt_make_u8vector(sizeof(transport_pkt), 0); - transport_pkt *pkt = (transport_pkt *) pmt_u8vector_writable_elements(v_packet, psize); - payload_len = 0; - - pkt->set_header(0, channel, 0, payload_len); - pkt->set_timestamp(0xffffffff); - - while(curr_subpkt < n_subpkts) { - - pmt_t subp = pmt_nth(curr_subpkt, subpackets); - pmt_t subp_cmd = pmt_nth(0, subp); - pmt_t subp_data = pmt_nth(1, subp); - - //--------- PING FIXED --------------// - if(pmt_eq(subp_cmd, s_op_ping_fixed)) { - - long urid = pmt_to_long(pmt_nth(0, subp_data)); - long pingval = pmt_to_long(pmt_nth(1, subp_data)); - - // USRP server sets request ID's to keep track of which application gets - // what response back. To allow a full 6-bits for an RID to the user, we - // keep a mapping and replace the RID's as the packets go in and out. If - // there are no RID's available, the command is thrown away silently. - long srid; - if((srid = next_rid()) == -1) - goto subpkt_bail; - - // We use a vector to store the owner of the ping request and will use it - // to send the request on any RX port they own. - d_rids[srid].owner = port->port_symbol(); - d_rids[srid].user_rid = urid; - - // Adds a ping after the previous command in the pkt - if(!pkt->cs_ping(srid, pingval)) - { - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(invocation_handle, - pmt_from_long(channel), - v_packet)); - - // Return the RID - d_rids[srid].owner = PMT_NIL; - - goto new_packet; - } - - if(verbose) - std::cout << "[USRP_SERVER] Received ping command request" - << " assigning RID " << srid << std::endl; - - } - - //----------- WRITE REG ---------------// - if(pmt_eq(subp_cmd, s_op_write_reg)) { - - long reg_num = pmt_to_long(pmt_nth(0, subp_data)); - long val = pmt_to_long(pmt_nth(1, subp_data)); - - if(!pkt->cs_write_reg(reg_num, val)) - { - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(invocation_handle, - pmt_from_long(channel), - v_packet)); - - goto new_packet; - } - - if(verbose) - std::cout << "[USRP_SERVER] Received write register request " - << "(" - << "Reg: " << reg_num << ", " - << "Val: " << val - << ")\n"; - } - - //------- WRITE REG MASKED ----------// - if(pmt_eq(subp_cmd, s_op_write_reg_masked)) { - - long reg_num = pmt_to_long(pmt_nth(0, subp_data)); - long val = pmt_to_long(pmt_nth(1, subp_data)); - long mask = pmt_to_long(pmt_nth(2, subp_data)); - - if(!pkt->cs_write_reg_masked(reg_num, val, mask)) - { - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(invocation_handle, - pmt_from_long(channel), - v_packet)); - - goto new_packet; - } - - if(verbose) - std::cout << "[USRP_SERVER] Received write register masked request\n"; - } - - //------------ READ REG --------------// - if(pmt_eq(subp_cmd, s_op_read_reg)) { - - long urid = pmt_to_long(pmt_nth(0, subp_data)); - long reg_num = pmt_to_long(pmt_nth(1, subp_data)); - - long srid; - if((srid = next_rid()) == -1) - goto subpkt_bail; - - d_rids[srid].owner = port->port_symbol(); - d_rids[srid].user_rid = urid; - - if(!pkt->cs_read_reg(srid, reg_num)) - { - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(invocation_handle, - pmt_from_long(channel), - v_packet)); - - // Return the rid - d_rids[srid].owner = PMT_NIL; - - goto new_packet; - } - - if(verbose) - std::cout << "[USRP_SERVER] Received read register request" - << " assigning RID " << srid << std::endl; - } - - //------------ DELAY --------------// - if(pmt_eq(subp_cmd, s_op_delay)) { - - long ticks = pmt_to_long(pmt_nth(0, subp_data)); - - if(!pkt->cs_delay(ticks)) - { - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(invocation_handle, - pmt_from_long(channel), - v_packet)); - - goto new_packet; - } - - if(verbose) - std::cout << "[USRP_SERVER] Received delay request of " - << ticks << " ticks\n"; - } - - //--------- I2C WRITE -----------// - // FIXME: could check that byte count does not exceed 2^8 which - // is the max length in the subpacket for # of bytes to read. - if(pmt_eq(subp_cmd, s_op_i2c_write)) { - - long i2c_addr = pmt_to_long(pmt_nth(0, subp_data)); - pmt_t data = pmt_nth(1, subp_data); - - // Get a readable address to the data which also gives us the length - size_t data_len; - uint8_t *i2c_data = (uint8_t *) pmt_u8vector_writable_elements(data, data_len); - - // Make the USB packet - if(!pkt->cs_i2c_write(i2c_addr, i2c_data, data_len)) - { - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(invocation_handle, - pmt_from_long(channel), - v_packet)); - - goto new_packet; - } - - if(verbose) - std::cout << "[USRP_SERVER] Received I2C write\n"; - } - - //----------- I2C Read -------------// - if(pmt_eq(subp_cmd, s_op_i2c_read)) { - - long urid = pmt_to_long(pmt_nth(0, subp_data)); - long i2c_addr = pmt_to_long(pmt_nth(1, subp_data)); - long i2c_bytes = pmt_to_long(pmt_nth(2, subp_data)); - - long srid; - if((srid = next_rid()) == -1) - goto subpkt_bail; - - d_rids[srid].owner = port->port_symbol(); - d_rids[srid].user_rid = urid; - - if(!pkt->cs_i2c_read(srid, i2c_addr, i2c_bytes)) - { - - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(invocation_handle, - pmt_from_long(channel), - v_packet)); - - d_rids[srid].owner = PMT_NIL; - - goto new_packet; - } - - if(verbose) - std::cout << "[USRP_SERVER] Received I2C read\n"; - } - - //--------- SPI WRITE -----------// - if(pmt_eq(subp_cmd, s_op_spi_write)) { - - long enables = pmt_to_long(pmt_nth(0, subp_data)); - long format = pmt_to_long(pmt_nth(1, subp_data)); - long opt = pmt_to_long(pmt_nth(2, subp_data)); - pmt_t data = pmt_nth(3, subp_data); - - // Get a readable address to the data which also gives us the length - size_t data_len; - uint8_t *spi_data = (uint8_t *) pmt_u8vector_writable_elements(data, data_len); - - // Make the USB packet - if(!pkt->cs_spi_write(enables, format, opt, spi_data, data_len)) - { - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(invocation_handle, - pmt_from_long(channel), - v_packet)); - - goto new_packet; - } - - if(verbose) - std::cout << "[USRP_SERVER] Received SPI write\n"; - } - - //--------- SPI READ -----------// - if(pmt_eq(subp_cmd, s_op_spi_read)) { - - long urid = pmt_to_long(pmt_nth(0, subp_data)); - long enables = pmt_to_long(pmt_nth(1, subp_data)); - long format = pmt_to_long(pmt_nth(2, subp_data)); - long opt = pmt_to_long(pmt_nth(3, subp_data)); - long n_bytes = pmt_to_long(pmt_nth(4, subp_data)); - - long srid; - if((srid = next_rid()) == -1) - goto subpkt_bail; - - d_rids[srid].owner = port->port_symbol(); - d_rids[srid].user_rid = urid; - - // Make the USB packet - if(!pkt->cs_spi_read(srid, enables, format, opt, n_bytes)) - { - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(invocation_handle, - pmt_from_long(channel), - v_packet)); - - // Return the rid - d_rids[srid].owner = PMT_NIL; - - goto new_packet; - } - - if(verbose) - std::cout << "[USRP_SERVER] Received SPI read\n"; - } - - subpkt_bail: - curr_subpkt++; - - } - - - // If the current packets length is > 0, we know there are subpackets that - // need to be sent out still. - if(pkt->payload_len() > 0) - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(invocation_handle, - pmt_from_long(channel), - v_packet)); - - return; -} - -/*! - * \brief Called by the handle_message() method when the incoming signal is a - * command to start reading samples from the USRP (cmd-start-recv-raw-samples). - * - * The \p port the command was sent on and the channel info (\p chan_info) of - * the channel are passed to ensure that the caller owns the channel. - * - * The \p data parameter should be in the format of a cmd-start-recv-raw-samples - * command where the first element in the list is an invocation handle, and the - * second is the channel the signal generator wants to receive the samples on. - */ -void -usrp_server::handle_cmd_start_recv_raw_samples( - mb_port_sptr port, - std::vector<struct channel_info> &chan_info, - pmt_t data) -{ - pmt_t invocation_handle = pmt_nth(0, data); - long channel = pmt_to_long(pmt_nth(1, data)); - - // Ensure the channel is valid and the caller owns the port - if(!check_valid(port, channel, chan_info, - pmt_list2(s_response_xmit_raw_frame, invocation_handle))) - return; - - // Already started receiving samples? (another start before a stop) - // Check the RX channel bitmask. - if(d_rx_chan_mask & (1 << channel)) { - port->send(s_response_recv_raw_samples, - pmt_list5(invocation_handle, - s_err_already_receiving, - PMT_NIL, - PMT_NIL, - PMT_NIL)); - return; - } - - // We only need to generate a 'start reading' command down to the - // low level interface if no other channel is already reading - // - // We carry this over the CS interface because the lower level - // interface does not care about the channel, we only demux it - // at the usrp_server on responses. - if(d_rx_chan_mask == 0) { - - if(verbose) - std::cout << "[USRP_SERVER] Sending read request down to start recv\n"; - - d_cs_usrp->send(s_cmd_usrp_start_reading, pmt_list1(invocation_handle)); - } - - d_rx_chan_mask |= 1<<channel; - - return; -} - -/*! - * \brief Called by the handle_message() method when the incoming signal is to - * stop receiving samples from the USRP (cmd-stop-recv-raw-samples). - * - * The \p port the command was sent on and the channel info (\p chan_info) of - * the channel are passed to ensure that the caller owns the channel. - * - * The \p data parameter should be in the format of a cmd-stop-recv-raw-samples - * command where the first element in the list is an invocation handle, and the - * second is the channel the signal generator wants to stop receiving the - * samples from. - */ -void -usrp_server::handle_cmd_stop_recv_raw_samples( - mb_port_sptr port, - std::vector<struct channel_info> &chan_info, - pmt_t data) -{ - pmt_t invocation_handle = pmt_nth(0, data); - long channel = pmt_to_long(pmt_nth(1, data)); - - // FIX ME : we have no responses to send an error... - // Ensure the channel is valid and the caller owns the port - //if(!check_valid(port, channel, chan_info, - // pmt_list2(s_response_xmit_raw_frame, invocation_handle))) - // return; - - // Remove this hosts bit from the receiver mask - d_rx_chan_mask &= ~(1<<channel); - - // We only need to generate a 'start reading' command down to the - // low level interface if no other channel is already reading - // - // We carry this over the CS interface because the lower level - // interface does not care about the channel, we only demux it - // at the usrp_server on responses. - if(d_rx_chan_mask == 0) { - - if(verbose) - std::cout << "[USRP_SERVER] Sending stop reading request down\n"; - - d_cs_usrp->send(s_cmd_usrp_stop_reading, pmt_list1(invocation_handle)); - } - - return; -} - -/*! - * \brief Called by the handle_message() method when an incoming signal is - * generated to USRP server that contains raw samples from the USRP. This - * method generates the response-recv-raw-samples signals that are the result of - * a cmd-start-recv-raw-samples signal. - * - * The raw lower-level packet is extracted from \p data, where the format for \p - * data is a PMT list. The PMT \p data list should contain an invocation handle - * as the first element, the status of the lower-level read as the second - * element, and a uniform vector representation of the packets as the third - * element. - * - * The packet contains a channel field that the samples are destined to, and the - * method determines where to send the samples based on this channel since each - * channel has an associated port which allocated it. - */ -void -usrp_server::handle_response_usrp_read(pmt_t data) -{ - - pmt_t invocation_handle = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - pmt_t v_pkt = pmt_nth(2, data); - - size_t n_bytes; - size_t ignore; - - if (d_fake_rx) { - - pmt_t pkt = pmt_nth(2, data); - - d_rx[0]->send(s_response_recv_raw_samples, - pmt_list5(PMT_F, - PMT_T, - pkt, - pmt_from_long(0xffff), - PMT_NIL)); - - return; - } - - // Extract the packet and return appropriately - transport_pkt *pkt = (transport_pkt *) pmt_u8vector_writable_elements(v_pkt, n_bytes); - - // The channel is used to find the port to pass the samples on - long channel = pkt->chan(); - long payload_len = pkt->payload_len(); - long port; - - // Ignore packets which seem to have incorrect size or size 0 - if(payload_len > pkt->max_payload() || payload_len == 0) - return; - - // If the packet is a C/S packet, parse it separately - if(channel == CONTROL_CHAN) { - parse_control_pkt(invocation_handle, pkt); - return; - } - - if((port = rx_port_index(d_chaninfo_rx[channel].owner)) == -1) - return; // Don't know where to send the sample... possibility on abrupt close - - pmt_t v_samples = pmt_make_u8vector(payload_len, 0); - uint8_t *samples = pmt_u8vector_writable_elements(v_samples, ignore); - - memcpy(samples, pkt->payload(), payload_len); - - // Build a properties dictionary to store things such as the RSSI - pmt_t properties = pmt_make_dict(); - - pmt_dict_set(properties, - pmt_intern("rssi"), - pmt_from_long(pkt->rssi())); - - if(pkt->overrun()) - pmt_dict_set(properties, - pmt_intern("overrun"), - PMT_T); - - if(pkt->underrun()) - pmt_dict_set(properties, - pmt_intern("underrun"), - PMT_T); - - d_rx[port]->send(s_response_recv_raw_samples, - pmt_list6(invocation_handle, - status, - v_samples, - pmt_from_long(pkt->timestamp()), - pmt_from_long(channel), - properties)); - return; -} - -/*! - * \brief Called by handle_response_usrp_read() when the incoming packet has a - * channel of CONTROL_CHAN. This means that the incoming packet contains a - * response for a command sent to the control channel, which this method will - * parse. - * - * The \p pkt parameter is a pointer to the full packet (transport_pkt) in - * memory. - * - * Given that all commands sent to the control channel that require responses - * will carry an RID (request ID), the method will use the RID passed back with - * the response to determine which port the response should be sent on. - */ -void -usrp_server::parse_control_pkt(pmt_t invocation_handle, transport_pkt *pkt) -{ - - long payload_len = pkt->payload_len(); - long curr_payload = 0; - long port; - - // We dispatch based on the control packet type, however we can extract the - // opcode and the length immediately which is consistent in all responses. - // - // Since each control packet can have multiple responses, we keep reading the - // lengths of each subpacket until we reach the payload length. - while(curr_payload < payload_len) { - - pmt_t sub_packet = pkt->read_subpacket(curr_payload); - pmt_t op_symbol = pmt_nth(0, sub_packet); - - int len = pkt->cs_len(curr_payload); - - if(verbose) - std::cout << "[USRP_SERVER] Parsing subpacket " - << op_symbol << " ... length " << len << std::endl; - - //----------------- PING RESPONSE ------------------// - if(pmt_eq(op_symbol, s_op_ping_fixed_reply)) { - - long srid = pmt_to_long(pmt_nth(1, sub_packet)); - pmt_t pingval = pmt_nth(2, sub_packet); - - long urid = d_rids[srid].user_rid; - - if(verbose) - std::cout << "[USRP_SERVER] Found ping response " - << "(" - << "URID: " << urid << ", " - << "SRID: " << srid << ", " - << "VAL: " << pingval - << ")\n"; - - // Do some bounds checking incase of bogus/corrupt responses - if(srid > D_MAX_RID) - return; - - pmt_t owner = d_rids[srid].owner; - - // Return the RID - d_rids[srid].owner = PMT_NIL; - - // FIXME: should be 1 response for all subpackets here ? - if((port = tx_port_index(owner)) != -1) - d_tx[port]->send(s_response_from_control_channel, - pmt_list4(invocation_handle, - PMT_T, - pmt_list2(s_op_ping_fixed_reply, // subp - pmt_list2(pmt_from_long(urid), - pingval)), - pmt_from_long(pkt->timestamp()))); - } - - //----------------- READ REG RESPONSE ------------------// - else if(pmt_eq(op_symbol, s_op_read_reg_reply)) { - - long srid = pmt_to_long(pmt_nth(1, sub_packet)); - pmt_t reg_num = pmt_nth(2, sub_packet); - pmt_t reg_val = pmt_nth(3, sub_packet); - - long urid = d_rids[srid].user_rid; - - if(verbose) - std::cout << "[USRP_SERVER] Found read register response " - << "(" - << "URID: " << urid << ", " - << "SRID: " << srid << ", " - << "REG: " << reg_num << ", " - << "VAL: " << reg_val - << ")\n"; - - // Do some bounds checking to avoid seg faults - if(srid > D_MAX_RID) - return; - - pmt_t owner = d_rids[srid].owner; - - // Return the RID - d_rids[srid].owner = PMT_NIL; - - // FIXME: should be 1 response for all subpackets here ? - if((port = tx_port_index(owner)) != -1) - d_tx[port]->send(s_response_from_control_channel, - pmt_list4(invocation_handle, - PMT_T, - pmt_list2(s_op_read_reg_reply, // subp - pmt_list3(pmt_from_long(urid), - reg_num, - reg_val)), - pmt_from_long(pkt->timestamp()))); - } - - //------------------ I2C READ REPLY -------------------// - else if(pmt_eq(op_symbol, s_op_i2c_read_reply)) { - - long srid = pmt_to_long(pmt_nth(1, sub_packet)); - pmt_t i2c_addr = pmt_nth(2, sub_packet); - pmt_t i2c_data = pmt_nth(3, sub_packet); - - long urid = d_rids[srid].user_rid; - - if(verbose) - std::cout << "[USRP_SERVER] Found i2c read reply " - << "(" - << "URID: " << urid << ", " - << "SRID: " << srid << ", " - << "Addr: " << i2c_addr << ", " - << "Data: " << i2c_data - << ")\n"; - - // Do some bounds checking to avoid seg faults - if(srid > D_MAX_RID) - return; - - pmt_t owner = d_rids[srid].owner; - - // Return the RID - d_rids[srid].owner = PMT_NIL; - - if((port = tx_port_index(owner)) != -1) - d_tx[port]->send(s_response_from_control_channel, - pmt_list4(invocation_handle, - PMT_T, - pmt_list2(s_op_i2c_read_reply, - pmt_list3(pmt_from_long(urid), - i2c_addr, - i2c_data)), - pmt_from_long(pkt->timestamp()))); - } - - //------------------ SPI READ REPLY -------------------// - else if(pmt_eq(op_symbol, s_op_spi_read_reply)) { - - long srid = pmt_to_long(pmt_nth(1, sub_packet)); - pmt_t spi_data = pmt_nth(2, sub_packet); - - long urid = d_rids[srid].user_rid; - - if(verbose) - std::cout << "[USRP_SERVER] Found SPI read reply " - << "(" - << "URID: " << urid << ", " - << "SRID: " << srid << ", " - << "Data: " << spi_data - << ")\n"; - - // Bounds check the RID - if(srid > D_MAX_RID) - return; - - pmt_t owner = d_rids[srid].owner; - - // Return the RID - d_rids[srid].owner = PMT_NIL; - - if((port = tx_port_index(owner)) != -1) - d_tx[port]->send(s_response_from_control_channel, - pmt_list4(invocation_handle, - PMT_T, - pmt_list2(s_op_spi_read_reply, - pmt_list2(pmt_from_long(urid), - spi_data)), - pmt_from_long(pkt->timestamp()))); - } - - // Each subpacket has an unaccounted for 2 bytes which is the opcode - // and the length field - curr_payload += len + 2; - - // All subpackets are 32-bit aligned - int align_offset = 4 - (curr_payload % 4); - - if(align_offset != 4) - curr_payload += align_offset; - } -} - -/*! - * \brief Used to recall all incoming signals that were deferred when USRP - * server was in the initialization state. - */ -void -usrp_server::recall_defer_queue() -{ - - std::vector<mb_message_sptr> recall; - - while(!d_defer_queue.empty()) { - recall.push_back(d_defer_queue.front()); - d_defer_queue.pop(); - } - - // Parse the messages that were queued while waiting for an open response - for(int i=0; i < (int)recall.size(); i++) - handle_message(recall[i]); - - return; -} - -/*! - * \brief Commonly called by any method which handles outgoing frames or control - * packets to the USRP to check if the port on which the signal was sent owns - * the channel the outgoing packet will be associated with. This helps ensure - * that applications do not send data on other application's ports. - * - * The \p port parameter is the port symbol that the caller wishes to determine - * owns the channel specified by \p chan_info. - * - * The \p signal_info parameter is a PMT list containing two elements: the - * response signal to use if the permissions are invalid, and the invocation - * handle that was passed. This allows the method to generate detailed failure - * responses to signals without having to return some sort of structured - * information which the caller must then parse and interpret to determine the - * failure type. - * - * \returns true if \p port owns the channel specified by \p chan_info, false - * otherwise. - */ -bool -usrp_server::check_valid(mb_port_sptr port, - long channel, - std::vector<struct channel_info> &chan_info, - pmt_t signal_info) -{ - - pmt_t response_signal = pmt_nth(0, signal_info); - pmt_t invocation_handle = pmt_nth(1, signal_info); - - // not a valid channel number? - if(channel >= (long)chan_info.size() && channel != CONTROL_CHAN) { - port->send(response_signal, - pmt_list2(invocation_handle, - s_err_channel_invalid)); - - if(verbose) - std::cout << "[USRP_SERVER] Invalid channel number for event " - << response_signal << std::endl; - return false; - } - - // not the owner of the port? - if(chan_info[channel].owner != port->port_symbol()) { - port->send(response_signal, - pmt_list2(invocation_handle, - s_err_channel_permission_denied)); - - if(verbose) - std::cout << "[USRP_SERVER] Invalid permissions" - << " for " << response_signal - << " from " << port->port_symbol() - << " proper owner is " << chan_info[channel].owner - << " on channel " << channel - << " invocation " << invocation_handle - << std::endl; - return false; - } - - return true; -} - -/*! - * \brief Finds the next available RID for internal USRP server use with control - * and status packets. - * - * \returns the next valid RID or -1 if no more RIDs are available. - */ -long -usrp_server::next_rid() -{ - for(int i = 0; i < D_MAX_RID; i++) - if(pmt_eqv(d_rids[i].owner, PMT_NIL)) - return i; - - if(verbose) - std::cout << "[USRP_SERVER] No RIDs left\n"; - return -1; -} - -/*! - * \brief Called by handle_message() when USRP server gets a response that the - * USRP was opened successfully to initialize the registers using the new - * register read/write control packets. - */ -void -usrp_server::initialize_registers() -{ - // We use handle_cmd_to_control_channel() to create the register writes using - // PMT_NIL as the response port to tell usrp_server not to pass the response - // up to any application. - if(verbose) - std::cout << "[USRP_SERVER] Initializing registers...\n"; - - // RX mode to normal (0) - set_register(FR_MODE, 0); - - // FPGA debugging? - if(d_fpga_debug) { - set_register(FR_DEBUG_EN, 1); - // FIXME: need to figure out exact register writes to control daughterboard - // pins that need to be written to - } else { - set_register(FR_DEBUG_EN, 0); - } - - // Set the transmit sample rate divisor, which is 4-1 - set_register(FR_TX_SAMPLE_RATE_DIV, 3); - - // Dboard IO buffer and register settings - set_register(FR_OE_0, (0xffff << 16) | 0x0000); - set_register(FR_IO_0, (0xffff << 16) | 0x0000); - set_register(FR_OE_1, (0xffff << 16) | 0x0000); - set_register(FR_IO_1, (0xffff << 16) | 0x0000); - set_register(FR_OE_2, (0xffff << 16) | 0x0000); - set_register(FR_IO_2, (0xffff << 16) | 0x0000); - set_register(FR_OE_3, (0xffff << 16) | 0x0000); - set_register(FR_IO_3, (0xffff << 16) | 0x0000); - - // zero Tx side Auto Transmit/Receive regs - set_register(FR_ATR_MASK_0, 0); - set_register(FR_ATR_TXVAL_0, 0); - set_register(FR_ATR_RXVAL_0, 0); - set_register(FR_ATR_MASK_1, 0); - set_register(FR_ATR_TXVAL_1, 0); - set_register(FR_ATR_RXVAL_1, 0); - set_register(FR_ATR_MASK_2, 0); - set_register(FR_ATR_TXVAL_2, 0); - set_register(FR_ATR_RXVAL_2, 0); - set_register(FR_ATR_MASK_3, 0); - set_register(FR_ATR_TXVAL_3, 0); - set_register(FR_ATR_RXVAL_3, 0); - - // Configure TX mux, this is a hacked value - set_register(FR_TX_MUX, 0x00000081); - - // Set the interpolation rate, which is the rate divided by 4, minus 1 - set_register(FR_INTERP_RATE, (d_interp_tx/4)-1); - - // Apparently this register changes again - set_register(FR_TX_MUX, 0x00000981); - - // Set the receive sample rate divisor, which is 2-1 - set_register(FR_RX_SAMPLE_RATE_DIV, 1); - - // DC offset - set_register(FR_DC_OFFSET_CL_EN, 0x0000000f); - - // Reset the DC correction offsets - set_register(FR_ADC_OFFSET_0, 0); - set_register(FR_ADC_OFFSET_1, 0); - - // Some hard-coded RX configuration - set_register(FR_RX_FORMAT, 0x00000300); - set_register(FR_RX_MUX, 1); - - // RX decimation rate is divided by two, then subtract 1 - set_register(FR_DECIM_RATE, (d_decim_rx/2)-1); - - // More hard coding - set_register(FR_RX_MUX, 0x000e4e41); - - // Resetting RX registers - set_register(FR_RX_PHASE_0, 0); - set_register(FR_RX_PHASE_1, 0); - set_register(FR_RX_PHASE_2, 0); - set_register(FR_RX_PHASE_3, 0); - set_register(FR_RX_FREQ_0, 0x28000000); - set_register(FR_RX_FREQ_1, 0); - set_register(FR_RX_FREQ_2, 0); - set_register(FR_RX_FREQ_3, 0); - - // Enable debug bus - set_register(FR_DEBUG_EN, 0xf); - set_register(FR_OE_0, -1); - set_register(FR_OE_1, -1); - set_register(FR_OE_2, -1); - set_register(FR_OE_3, -1); - - // DEBUGGING - //check_register_initialization(); -} - -// FIXME: used for debugging to determine if all the registers are actually -// being set correctly -void -usrp_server::check_register_initialization() -{ - // RX mode to normal (0) - read_register(FR_MODE); - - // FPGA debugging? - if(d_fpga_debug) { - read_register(FR_DEBUG_EN); - // FIXME: need to figure out exact register writes to control daughterboard - // pins that need to be written to - } else { - read_register(FR_DEBUG_EN); - } - - // Set the transmit sample rate divisor, which is 4-1 - read_register(FR_TX_SAMPLE_RATE_DIV); - - // Dboard IO buffer and register settings - read_register(FR_OE_0); - read_register(FR_IO_0); - read_register(FR_OE_1); - read_register(FR_IO_1); - read_register(FR_OE_2); - read_register(FR_IO_2); - read_register(FR_OE_3); - read_register(FR_IO_3); - - // zero Tx side Auto Transmit/Receive regs - read_register(FR_ATR_MASK_0); - read_register(FR_ATR_TXVAL_0); - read_register(FR_ATR_RXVAL_0); - read_register(FR_ATR_MASK_1); - read_register(FR_ATR_TXVAL_1); - read_register(FR_ATR_RXVAL_1); - read_register(FR_ATR_MASK_2); - read_register(FR_ATR_TXVAL_2); - read_register(FR_ATR_RXVAL_2); - read_register(FR_ATR_MASK_3); - read_register(FR_ATR_TXVAL_3); - read_register(FR_ATR_RXVAL_3); - - // Configure TX mux, this is a hacked value - read_register(FR_TX_MUX); - - // Set the interpolation rate, which is the rate divided by 4, minus 1 - read_register(FR_INTERP_RATE); - - // Apparently this register changes again - read_register(FR_TX_MUX); - - // Set the receive sample rate divisor, which is 2-1 - read_register(FR_RX_SAMPLE_RATE_DIV); - - // DC offset - read_register(FR_DC_OFFSET_CL_EN); - - // Reset the DC correction offsets - read_register(FR_ADC_OFFSET_0); - read_register(FR_ADC_OFFSET_1); - - // Some hard-coded RX configuration - read_register(FR_RX_FORMAT); - read_register(FR_RX_MUX); - - // RX decimation rate is divided by two, then subtract 1 - read_register(FR_DECIM_RATE); - - // More hard coding - read_register(FR_RX_MUX); - - // Resetting RX registers - read_register(FR_RX_PHASE_0); - read_register(FR_RX_PHASE_1); - read_register(FR_RX_PHASE_2); - read_register(FR_RX_PHASE_3); - read_register(FR_RX_FREQ_0); - read_register(FR_RX_FREQ_1); - read_register(FR_RX_FREQ_2); - read_register(FR_RX_FREQ_3); -} - -/*! - * \brief Used to generate FPGA register write commands to reset all of the FPGA - * registers to a value of 0. - */ -void -usrp_server::reset_all_registers() -{ - for(int i=0; i<64; i++) - set_register(i, 0); -} - -/*! - * \brief Used internally by USRP server to generate a control/status packet - * which contains a register write. - * - * The \p reg parameter is the register number that the value \p val will be - * written to. - */ -void -usrp_server::set_register(long reg, long val) -{ - size_t psize; - long payload_len = 0; - - pmt_t v_packet = pmt_make_u8vector(sizeof(transport_pkt), 0); - transport_pkt *pkt = (transport_pkt *) pmt_u8vector_writable_elements(v_packet, psize); - - pkt->set_header(0, CONTROL_CHAN, 0, payload_len); - pkt->set_timestamp(0xffffffff); - - pkt->cs_write_reg(reg, val); - - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(PMT_NIL, - pmt_from_long(CONTROL_CHAN), - v_packet)); -} - -/*! - * \brief Used internally by USRP server to generate a control/status packet - * which contains a register read. This is important to use internally so that - * USRP server can bypass the use of RIDs with register reads, as they are not - * needed and it would use up the finite number of RIDs available for use for - * applications to receive responses. - * - * The \p reg parameter is the register number that the value should be read - * from. - */ -void -usrp_server::read_register(long reg) -{ - size_t psize; - long payload_len = 0; - - pmt_t v_packet = pmt_make_u8vector(sizeof(transport_pkt), 0); - transport_pkt *pkt = (transport_pkt *) pmt_u8vector_writable_elements(v_packet, psize); - - pkt->set_header(0, CONTROL_CHAN, 0, payload_len); - pkt->set_timestamp(0xffffffff); - - pkt->cs_read_reg(0, reg); - - d_cs_usrp->send(s_cmd_usrp_write, - pmt_list3(PMT_NIL, - pmt_from_long(CONTROL_CHAN), - v_packet)); -} - -REGISTER_MBLOCK_CLASS(usrp_server); diff --git a/usrp/limbo/inband/usrp_server.h b/usrp/limbo/inband/usrp_server.h deleted file mode 100644 index dd1825d57..000000000 --- a/usrp/limbo/inband/usrp_server.h +++ /dev/null @@ -1,131 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef INCLUDED_USRP_SERVER_H -#define INCLUDED_USRP_SERVER_H - -#include <mblock/mblock.h> -#include <vector> -#include <queue> -#include <fstream> -#include <usrp_inband_usb_packet.h> - -typedef usrp_inband_usb_packet transport_pkt; // makes conversion to gigabit easy - -/*! - * \brief Implements the lowest-level mblock usb_interface to the USRP - */ -class usrp_server : public mb_mblock -{ -public: - - // our ports - enum port_types { - RX_PORT = 0, - TX_PORT = 1 - }; - static const int N_PORTS = 4; - std::vector<mb_port_sptr> d_tx, d_rx; - mb_port_sptr d_cs; - mb_port_sptr d_cs_usrp; - - static const int D_USB_CAPACITY = 32 * 1024 * 1024; - static const int D_MAX_CHANNELS = 16; - long d_ntx_chan; - long d_nrx_chan; - - pmt_t d_usrp_dict; - - bool d_fpga_debug; - - long d_interp_tx; - long d_decim_rx; - - // Keep track of the request IDs - struct rid_info { - pmt_t owner; - long user_rid; - - rid_info() { - owner = PMT_NIL; - user_rid = 0; - } - }; - - static const long D_MAX_RID = 64; - std::vector<rid_info> d_rids; - - struct channel_info { - long assigned_capacity; // the capacity currently assignedby the channel - pmt_t owner; // port ID of the owner of the channel - - channel_info() { - assigned_capacity = 0; - owner = PMT_NIL; - } - }; - - long d_rx_chan_mask; // A bitmask representing the channels in the - // receiving state - - std::vector<struct channel_info> d_chaninfo_tx; - std::vector<struct channel_info> d_chaninfo_rx; - - std::queue<mb_message_sptr> d_defer_queue; - - bool d_defer; - bool d_opened; - - bool d_fake_rx; - -public: - usrp_server(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg); - ~usrp_server(); - - void initial_transition(); - void handle_message(mb_message_sptr msg); - -protected: - static int max_capacity() { return D_USB_CAPACITY; } - -private: - void handle_cmd_allocate_channel(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data); - void handle_cmd_deallocate_channel(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data); - void handle_cmd_xmit_raw_frame(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data); - void handle_cmd_to_control_channel(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data); - void handle_cmd_start_recv_raw_samples(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data); - void handle_cmd_stop_recv_raw_samples(mb_port_sptr port, std::vector<struct channel_info> &chan_info, pmt_t data); - int rx_port_index(pmt_t port_id); - int tx_port_index(pmt_t port_id); - long current_capacity_allocation(); - void recall_defer_queue(); - void reset_channels(); - void handle_response_usrp_read(pmt_t data); - bool check_valid(mb_port_sptr port, long channel, std::vector<struct channel_info> &chan_info, pmt_t signal_info); - void parse_control_pkt(pmt_t invocation_handle, transport_pkt *pkt); - long next_rid(); - void initialize_registers(); - void set_register(long reg, long val); - void read_register(long reg); - void check_register_initialization(); - void reset_all_registers(); -}; - -#endif /* INCLUDED_USRP_SERVER_H */ diff --git a/usrp/limbo/inband/usrp_server.mbh b/usrp/limbo/inband/usrp_server.mbh deleted file mode 100644 index ed7943fc3..000000000 --- a/usrp/limbo/inband/usrp_server.mbh +++ /dev/null @@ -1,255 +0,0 @@ -;; -*- scheme -*- ; not really, but tells emacs how to format this -;; -;; Copyright 2007 Free Software Foundation, Inc. -;; -;; This file is part of GNU Radio -;; -;; GNU Radio is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. -;; -;; GNU Radio is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License along -;; with this program; if not, write to the Free Software Foundation, Inc., -;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -;; - -;; ---------------------------------------------------------------- -;; This is an mblock header file -;; -;; The format is very much a work-in-progress. -;; It'll be compiled to C++. -;; ---------------------------------------------------------------- - -;; In the outgoing messages described below, invocation-handle is an -;; identifier provided by the client to tag the method invocation. -;; The identifier will be returned with the response, to provide the -;; client with a mechanism to match asynchronous responses with the -;; commands that generate them. The value of the invocation-handle is -;; opaque the the server, and is not required by the server to be -;; unique. -;; -;; In the incoming messages described below, invocation-handle is the -;; identifier provided by the client in the prompting invocation. The -;; identifier is returned with the response, so that the client has a -;; mechanism to match asynchronous responses with the commands that -;; generated them. -;; -;; status is either #t, indicating success, or a symbol indicating an error. -;; All symbol's names shall begin with %error- - - -;; ---------------------------------------------------------------- -;; usrp-channel -;; -;; The protocol class is defined from the client's point-of-view. -;; (The client port is unconjugated, the server port is conjugated.) - -(define-protocol-class usrp-channel - - (:outgoing - - (cmd-allocate-channel invocation-handle capacity-reservation) - - ;; The cmd-allocate-channel message requests that the server - ;; allocates a logical channel in the FPGA for use. - ;; capacity-reservation specifies the number of bytes/s of - ;; interconnect capacity (USB or ethernet) to reserve for this - ;; channel. (The reservation is just a sanity check, no OS - ;; specific mechanism is used.) - - (cmd-deallocate-channel invocation-handle channel) - - ;; The integer channel specifies the channel to deallocate. - - ) - - (:incoming - - - (response-allocate-channel invocation-handle status channel) - - ;; If successful, a channel the specified capacity was allocated. - ;; channel, an integer, indicates which channel was allocated. - - (response-deallocate-channel invocation-handle status) - - ;; If successful, the specified channel and associated interconnect - ;; capacity were deallocated. - - ) - ) - -;; ---------------------------------------------------------------- -;; usrp-low-level-cs -;; -;; The protocol class is defined from the client's point-of-view. -;; (The client port is unconjugated, the server port is conjugated.) -;; -;; This defines a low level control and status interface to the usrp. -;; This will probably be replaced (or at least augmented) with a -;; higher level interface. For now, this will allow us to get on -;; the air. -;; -;; The subpackets are lists containing the relevant parameters. The -;; server will marshall them appropriately. Below is a list of -;; subpackets. See inband-signaling-usb for details. The opcodes are -;; symbols; unless otherwise indicated the remaining parameters are -;; integers. rid values are limited to 3-bits. -;; -;; (op-ping-fixed rid ping-value) -;; (op-ping-fixed-reply rid ping-value) -;; (op-write-reg reg-number reg-value) -;; (op-write-reg-masked reg-number reg-value mask-value) -;; (op-read-reg rid reg-number) -;; (op-read-reg-reply rid reg-number reg-value) -;; (op-i2c-write i2c-addr u8-vec) -;; (op-i2c-read rid i2c-addr nbytes) -;; (op-i2c-read-reply rid i2c-addr u8-vec) -;; (op-spi-write enables format opt-header-bytes u8-vec) -;; (op-spi-read rid enables format opt-header-bytes nbytes) -;; (op-spi-read-reply rid u8-vec) -;; (op-delay ticks) - - -(define-protocol-class usrp-low-level-cs - - (:outgoing - - (cmd-to-control-channel invocation-handle list-of-subpackets) - - ) - - (:incoming - - (response-from-control-channel invocation-handle status list-of-subpackets timestamp) - - ) - ) - -;; ---------------------------------------------------------------- -;; usrp-tx -;; -;; The protocol class is defined from the client's point-of-view. -;; (The client port is unconjugated, the server port is conjugated.) - -(define-protocol-class usrp-tx - (:include usrp-channel) - (:include usrp-low-level-cs) - - (:outgoing - - (cmd-xmit-raw-frame invocation-handle channel samples timestamp properties) - - ;; The argument channel must be an integer. It specifies the - ;; channel on which the frame of samples will be be sent. - ;; - ;; samples must be a uniform numeric vector. The contents of the - ;; sample vector is treated as opaque and is passed on to the FPGA - ;; unmodified. It is the responsibility of the sender to ensure - ;; that the binary format is sensible for the current FPGA - ;; configuration. - ;; - ;; timestamp is a 32-bit integer that specifies the time at which - ;; the first sample in samples shall be sent to the D/A converter. - ;; The format and interpration of time is specified in the file - ;; inband-signaling-usb - ) - - (:incoming - - (response-xmit-raw-frame invocation-handle status) - - ;; If successful, the samples of the associated frame have been - ;; transmitted to the USRP. This message may be used to implement - ;; Tx flow control. The client could for example implement a - ;; policy of never having more than 4 unacknowledged - ;; cmd-xmit-raw-frame's outstanding. - - ) - ) - -;; ---------------------------------------------------------------- -;; usrp-rx -;; -;; The protocol class is defined from the client's point-of-view. -;; (The client port is unconjugated, the server port is conjugated.) - -(define-protocol-class usrp-rx - (:include usrp-channel) - (:include usrp-low-level-cs) - - (:outgoing - - (cmd-start-recv-raw-samples invocation-handle channel) - - ;; The argument channel must be an integer. It specifies the - ;; channel from which frames of samples will be be received. The - ;; server will return response-recv-raw-samples messages until a - ;; cmd-stop-recv-raw-samples message is received. - - (cmd-stop-recv-raw-samples invocation-handle channel) - - ;; The argument channel must be an integer. There is no reply to - ;; this message. - - ) - - (:incoming - - (response-recv-raw-samples invocation-handle status samples timestamp channel properties) - - ;; samples is a uniform numeric vector. The contents of the sample - ;; vector is treated as opaque and is passed from the FPGA - ;; unmodified. It is the responsibility of the receiver to decode - ;; the binary format as appropriate for the current FPGA - ;; configuration. - ;; - ;; timestamp is a 32-bit integer that specifies the time at which - ;; the first sample in samples was received from the A/D converter. - ;; The format and interpretation of time is as specified in the - ;; file inband-signaling-usb. - ;; - ;; properties is a dictionary containing additional (key, value) - ;; pairs associated with the reception of these samples. In - ;; particular, the map may contain the Received Signal Strength - ;; Indication (RSSI) reported by the front end at the time the - ;; first sample was received from the A/D. - - ) - ) - - -;; ---------------------------------------------------------------- -;; usrp-server-cs -;; -;; Control and status port for usrp-server -;; -;; The protocol class is defined from the client's point-of-view. -;; (The client port is unconjugated, the server port is conjugated.) - -(define-protocol-class usrp-server-cs - - (:outgoing - (cmd-open invocation-handle which-usrp) - (cmd-close invocation-handle) - (cmd-max-capacity invocation-handle) - (cmd-ntx-chan invocation-handle) - (cmd-nrx-chan invocation-handle) - (cmd-current-capacity-allocation invocation-handle) - ) - - (:incoming - (response-open invocation-handle status) - (response-close invocation-handle status) - (response-max-capacity invocation-handle status capacity) - (response-ntx-chan invocation-handle status ntx-chan) - (response-nrx-chan invocation-handle status nrx-chan) - (response-current-capacity-allocation invocation-handle status capacity) - ) - ) diff --git a/usrp/limbo/inband/usrp_tx.cc b/usrp/limbo/inband/usrp_tx.cc deleted file mode 100644 index 0d4a84619..000000000 --- a/usrp/limbo/inband/usrp_tx.cc +++ /dev/null @@ -1,150 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <usrp_tx.h> -#include <iostream> -#include <usb.h> -#include <mblock/class_registry.h> -#include <usrp_inband_usb_packet.h> -#include <fpga_regs_common.h> -#include <usrp_standard.h> -#include <stdio.h> - -#include <symbols_usrp_tx_cs.h> - -typedef usrp_inband_usb_packet transport_pkt; - -static const bool verbose = false; - -usrp_tx::usrp_tx(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(rt, instance_name, user_arg), - d_disk_write(false) -{ - d_cs = define_port("cs", "usrp-tx-cs", true, mb_port::EXTERNAL); - - //d_disk_write=true; - - if(d_disk_write) { - d_ofile.open("tx_data.dat",std::ios::binary|std::ios::out); - d_cs_ofile.open("tx_cs.dat",std::ios::binary|std::ios::out); - } -} - -usrp_tx::~usrp_tx() -{ - if(d_disk_write) { - d_ofile.close(); - d_cs_ofile.close(); - } -} - -void -usrp_tx::initial_transition() -{ - -} - -/*! - * \brief Handles incoming signals to to the m-block, wihch should only ever be - * a single message: cmd-usrp-tx-write. - */ -void -usrp_tx::handle_message(mb_message_sptr msg) -{ - pmt_t event = msg->signal(); - pmt_t port_id = msg->port_id(); - pmt_t data = msg->data(); - - // Theoretically only have 1 message to ever expect, but - // want to make sure its at least what we want - if(pmt_eq(port_id, d_cs->port_symbol())) { - - if(pmt_eqv(event, s_cmd_usrp_tx_write)) - write(data); - } -} - -/*! - * \brief Performs the actual writing of data to the USB bus, called by - * handle_message() when a cmd-usrp-tx-write signal is received. - * - * The \p data parameter is a PMT list which contains three mandatory elements, - * in the following order: an invocation handle, a channel, and a uniform vector - * of memory which contains the packets to be written to the bus. - */ -void -usrp_tx::write(pmt_t data) -{ - pmt_t invocation_handle = pmt_nth(0, data); - pmt_t channel = pmt_nth(1, data); - pmt_t v_packets = pmt_nth(2, data); - d_utx = boost::any_cast<usrp_standard_tx_sptr>(pmt_any_ref(pmt_nth(3, data))); - - size_t n_bytes; - bool underrun; // this will need to go, as it is taken care of in the packet headers - - transport_pkt *pkts = (transport_pkt *) pmt_u8vector_writable_elements(v_packets, n_bytes); - - int ret = d_utx->write (pkts, n_bytes, &underrun); - - if (0 && underrun) - fprintf(stderr, "uU"); - - if (ret == (int) n_bytes) { - if (verbose) - std::cout << "[usrp_server] Write of " << n_bytes << " successful\n"; - // need to respond with the channel so the USRP server knows who to forward the result of - // the write to by looking up the owner of the channel - d_cs->send(s_response_usrp_tx_write, - pmt_list3(invocation_handle, PMT_T, channel)); - } - else { - if (verbose) - std::cout << "[usrp_server] Error writing " << n_bytes << " bytes to USB bus\n"; - d_cs->send(s_response_usrp_tx_write, - pmt_list3(invocation_handle, PMT_F, channel)); - } - - long n_packets = - static_cast<long>(std::ceil(n_bytes / (double)transport_pkt::max_pkt_size())); - - for(int i=0; i < n_packets; i++) { - - if(d_disk_write) { - if(pkts[i].chan() == CONTROL_CHAN) - d_cs_ofile.write((const char *)&pkts[i], transport_pkt::max_pkt_size()); - else - d_ofile.write((const char *)&pkts[i], transport_pkt::max_pkt_size()); - - d_cs_ofile.flush(); - d_ofile.flush(); - } - } - - - return; -} - -REGISTER_MBLOCK_CLASS(usrp_tx); diff --git a/usrp/limbo/inband/usrp_tx.h b/usrp/limbo/inband/usrp_tx.h deleted file mode 100644 index d3a6f8b54..000000000 --- a/usrp/limbo/inband/usrp_tx.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef INCLUDED_USRP_TX_H -#define INCLUDED_USRP_TX_H - -#include <mblock/mblock.h> -#include <fstream> -#include "usrp_standard.h" - -/*! - * \brief Implements the low level usb interface to the USRP - */ -class usrp_tx : public mb_mblock -{ - mb_port_sptr d_cs; - usrp_standard_tx_sptr d_utx; - - bool d_disk_write; - std::ofstream d_ofile; - std::ofstream d_cs_ofile; - - public: - usrp_tx(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg); - ~usrp_tx(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - private: - void write(pmt_t data); -}; - - -#endif /* INCLUDED_USRP_TX_H */ - diff --git a/usrp/limbo/inband/usrp_tx_stub.cc b/usrp/limbo/inband/usrp_tx_stub.cc deleted file mode 100644 index c78b1a7b8..000000000 --- a/usrp/limbo/inband/usrp_tx_stub.cc +++ /dev/null @@ -1,344 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <iostream> -#include <vector> -#include <usb.h> -#include <mblock/class_registry.h> -#include <usrp_tx_stub.h> -#include <usrp_inband_usb_packet.h> -#include <fpga_regs_common.h> -#include "usrp_standard.h" -#include <stdio.h> -#include <fstream> -#include <usrp_rx_stub.h> - -#include <symbols_usrp_tx_cs.h> - -typedef usrp_inband_usb_packet transport_pkt; - -static const bool verbose = false; - -usrp_tx_stub::usrp_tx_stub(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(rt, instance_name, user_arg), - d_disk_write(false) -{ - d_cs = define_port("cs", "usrp-tx-cs", true, mb_port::EXTERNAL); - - //d_disk_write=true; - - if(d_disk_write) { - d_ofile.open("tx_stub_data.dat",std::ios::binary|std::ios::out); - d_cs_ofile.open("tx_stub_cs.dat",std::ios::binary|std::ios::out); - } -} - -usrp_tx_stub::~usrp_tx_stub() -{ - if(d_disk_write) { - d_ofile.close(); - d_cs_ofile.close(); - } -} - -void -usrp_tx_stub::initial_transition() -{ - -} - -void -usrp_tx_stub::handle_message(mb_message_sptr msg) -{ - pmt_t event = msg->signal(); - pmt_t port_id = msg->port_id(); - pmt_t data = msg->data(); - - // Theoretically only have 1 message to ever expect, but - // want to make sure its at least what we want - if(pmt_eq(port_id, d_cs->port_symbol())) { - - if(pmt_eqv(event, s_cmd_usrp_tx_write)) - write(data); - } -} - -void -usrp_tx_stub::write(pmt_t data) -{ - pmt_t invocation_handle = pmt_nth(0, data); - pmt_t channel = pmt_nth(1, data); - pmt_t v_packets = pmt_nth(2, data); - d_utx = boost::any_cast<usrp_standard_tx *>(pmt_any_ref(pmt_nth(3, data))); - - size_t n_bytes; - - transport_pkt *pkts = (transport_pkt *) pmt_u8vector_writable_elements(v_packets, n_bytes); - long n_packets = static_cast<long>(std::ceil(n_bytes / (double)transport_pkt::max_pkt_size())); - - // Parse the packets looking for C/S packets and dump them to a disk if - // necessary - for(long i=0; i<n_packets; i++) { - - if(d_disk_write) { - if(pkts[i].chan() == CONTROL_CHAN) - d_cs_ofile.write((const char *)&pkts[i], transport_pkt::max_pkt_size()); - else - d_ofile.write((const char *)&pkts[i], transport_pkt::max_pkt_size()); - - d_cs_ofile.flush(); - d_ofile.flush(); - } - - if(pkts[i].chan() == CONTROL_CHAN) - parse_cs(invocation_handle, pkts[i]); - } - - d_cs->send(s_response_usrp_tx_write, - pmt_list3(invocation_handle, PMT_T, channel)); - - return; -} - -void -usrp_tx_stub::parse_cs(pmt_t invocation_handle, transport_pkt pkt) -{ - - long payload_len = pkt.payload_len(); - long curr_payload = 0; - - size_t ignore; - - // There is the possibility that the responses for a single USB packet full of - // CS packets will not fit back in a single USB packet, considering some - // responses are greater than their commands (read registers). - new_packet: - pmt_t v_pkt = pmt_make_u8vector(sizeof(transport_pkt), 0); - - transport_pkt *q_pkt = - (transport_pkt *) pmt_u8vector_writable_elements(v_pkt, ignore); - - q_pkt->set_header(0, CONTROL_CHAN, 0, 0); - q_pkt->set_timestamp(0xffffffff); - - // We dispatch based on the control packet type, however we can extract the - // opcode and the length immediately which is consistent in all responses. - // - // Since each control packet can have multiple responses, we keep reading the - // lengths of each subpacket until we reach the payload length. - while(curr_payload < payload_len) { - - pmt_t sub_packet = pkt.read_subpacket(curr_payload); - pmt_t op_symbol = pmt_nth(0, sub_packet); - - int len = pkt.cs_len(curr_payload); - - if(verbose) - std::cout << "[USRP_TX_STUB] Parsing subpacket " - << op_symbol << " ... length " << len << std::endl; - - //----------------- PING FIXED ------------------// - if(pmt_eq(op_symbol, s_op_ping_fixed)) { - - long rid = pmt_to_long(pmt_nth(1, sub_packet)); - long pingval = pmt_to_long(pmt_nth(2, sub_packet)); - - // Generate a reply and put it in the queue for the RX stub to read - if(!q_pkt->cs_ping_reply(rid, pingval)) - goto new_packet; - - if(verbose) - std::cout << "[USRP_TX_STUB] Generated ping response " - << "(" - << "RID: " << rid << ", " - << "VAL: " << pingval - << ")\n"; - } - - //----------------- READ REG ------------------// - if(pmt_eq(op_symbol, s_op_read_reg)) { - - long rid = pmt_to_long(pmt_nth(1, sub_packet)); - long reg_num = pmt_to_long(pmt_nth(2, sub_packet)); - long reg_val = 0xdeef; - - // Generate a reply and put it in the queue for the RX stub to read - if(!q_pkt->cs_read_reg_reply(rid, reg_num, reg_val)) - goto new_packet; - - if(verbose) - std::cout << "[USRP_TX_STUB] Generated read register response " - << "(" - << "RID: " << rid << ", " - << "REG: " << reg_num << ", " - << "VAL: " << reg_val - << ")\n"; - } - - //----------------- DELAY ------------------// - if(pmt_eq(op_symbol, s_op_delay)) { - - long ticks = pmt_to_long(pmt_nth(1, sub_packet)); - - if(verbose) - std::cout << "[USRP_TX_STUB] Received delay command " - << "(" - << "Ticks: " << ticks - << ")\n"; - } - - //----------------- WRITE REG ------------------// - if(pmt_eq(op_symbol, s_op_write_reg)) { - - pmt_t reg_num = pmt_nth(1, sub_packet); - pmt_t reg_val = pmt_nth(2, sub_packet); - - if(verbose) - std::cout << "[USRP_TX_STUB] Received write register command " - << "(" - << "RegNum: " << reg_num << ", " - << "Val: " << reg_val - << ")\n"; - } - - //----------------- WRITE REG MASK ---------------// - if(pmt_eq(op_symbol, s_op_write_reg_masked)) { - - pmt_t reg_num = pmt_nth(1, sub_packet); - pmt_t reg_val = pmt_nth(2, sub_packet); - pmt_t mask = pmt_nth(3, sub_packet); - - if(verbose) - std::cout << "[USRP_TX_STUB] Received write register command " - << "(" - << "RegNum: " << reg_num << ", " - << "Val: " << reg_val << ", " - << "Mask: " << mask - << ")\n"; - } - - //---------------- I2C WRITE ------------------// - if(pmt_eq(op_symbol, s_op_i2c_write)) { - pmt_t i2c_addr = pmt_nth(1, sub_packet); - pmt_t i2c_data = pmt_nth(2, sub_packet); - - if(verbose) - std::cout << "[USRP_TX_STUB] Received i2c write command " - << "(" - << "Addr: " << i2c_addr << ", " - << "Data: " << i2c_data - << ")\n"; - } - - //---------------- I2C READ ------------------// - if(pmt_eq(op_symbol, s_op_i2c_read)) { - long rid = pmt_to_long(pmt_nth(1, sub_packet)); - long i2c_addr = pmt_to_long(pmt_nth(2, sub_packet)); - long i2c_bytes = pmt_to_long(pmt_nth(3, sub_packet)); - - // Create data to place as a response, filled with 0xff - size_t ignore; - pmt_t i2c_data = pmt_make_u8vector(i2c_bytes, 0xff); - uint8_t *w_data = (uint8_t *) pmt_u8vector_writable_elements(i2c_data, ignore); - - // Generate a reply and put it in the queue for the RX stub to read - if(!q_pkt->cs_i2c_read_reply(rid, i2c_addr, w_data, i2c_bytes)) - goto new_packet; - - if(verbose) - std::cout << "[USRP_TX_STUB] Received i2c read " - << "(" - << "RID: " << rid << ", " - << "Addr: " << i2c_addr << ", " - << "Bytes: " << i2c_bytes - << ")\n"; - } - - //---------------- SPI WRITE ------------------// - if(pmt_eq(op_symbol, s_op_spi_write)) { - long enables = pmt_to_long(pmt_nth(1, sub_packet)); - long format = pmt_to_long(pmt_nth(2, sub_packet)); - long opt = pmt_to_long(pmt_nth(3, sub_packet)); - pmt_t data = pmt_nth(4, sub_packet); - - if(verbose) - std::cout << "[USRP_TX_STUB] Received spi write command " - << "(" - << "Enables: " << enables << ", " - << "Format: " << format << ", " - << "Options: " << opt << ", " - << "Data: " << data - << ")\n"; - } - - //---------------- SPI READ ------------------// - if(pmt_eq(op_symbol, s_op_spi_read)) { - long rid = pmt_to_long(pmt_nth(1, sub_packet)); - long enables = pmt_to_long(pmt_nth(2, sub_packet)); - long format = pmt_to_long(pmt_nth(3, sub_packet)); - long opt = pmt_to_long(pmt_nth(4, sub_packet)); - long n_bytes = pmt_to_long(pmt_nth(5, sub_packet)); - - // Create data to place as a fake response - size_t ignore; - pmt_t spi_data = pmt_make_u8vector(n_bytes, 0xff); - uint8_t *w_data = (uint8_t *) pmt_u8vector_writable_elements(spi_data, ignore); - - // Generate a reply and put it in the queue for the RX stub to read - if(!q_pkt->cs_spi_read_reply(rid, w_data, n_bytes)) - goto new_packet; - - if(verbose) - std::cout << "[USRP_TX_STUB] Received spi read command " - << "(" - << "RID: " << rid << ", " - << "Enables: " << enables << ", " - << "Format: " << format << ", " - << "Options: " << opt << ", " - << "Bytes: " << n_bytes - << ")\n"; - - } - - // Each subpacket has an unaccounted for 2 bytes which is the opcode - // and the length field - curr_payload += len + 2; - - // All subpackets are 32-bit aligned - int align_offset = 4 - (curr_payload % 4); - - if(align_offset != 4) - curr_payload += align_offset; - - } - - // If the packet has data in the payload, it needs queued - if(q_pkt->payload_len() > 0) - d_cs_queue.push(pmt_list2(invocation_handle, v_pkt)); - - return; -} - -REGISTER_MBLOCK_CLASS(usrp_tx_stub); diff --git a/usrp/limbo/inband/usrp_tx_stub.h b/usrp/limbo/inband/usrp_tx_stub.h deleted file mode 100644 index b81037ad7..000000000 --- a/usrp/limbo/inband/usrp_tx_stub.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef INCLUDED_USRP_TX_STUB_H -#define INCLUDED_USRP_TX_STUB_H - -#include <mblock/mblock.h> -#include <vector> -#include "usrp_standard.h" -#include <fstream> -#include <usrp_inband_usb_packet.h> - -typedef usrp_inband_usb_packet transport_pkt; - -/*! - * \brief Implements the low level usb interface to the USRP - */ -class usrp_tx_stub : public mb_mblock -{ - public: - - mb_port_sptr d_cs; - usrp_standard_tx* d_utx; - - std::ofstream d_ofile; - std::ofstream d_cs_ofile; - - bool d_disk_write; - - public: - usrp_tx_stub(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg); - ~usrp_tx_stub(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - - private: - void write(pmt_t data); - void parse_cs(pmt_t invocation_handle, transport_pkt pkt); - -}; - - -#endif /* INCLUDED_USRP_TX_STUB_H */ - diff --git a/usrp/limbo/inband/usrp_usb_interface.cc b/usrp/limbo/inband/usrp_usb_interface.cc deleted file mode 100644 index fb7109a5a..000000000 --- a/usrp/limbo/inband/usrp_usb_interface.cc +++ /dev/null @@ -1,601 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008,2009 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <usrp_usb_interface.h> - -#include <iostream> -#include <vector> -#include <usb.h> -#include <mblock/class_registry.h> -#include <usrp_inband_usb_packet.h> -#include <fpga_regs_common.h> -#include "usrp_rx.h" -#include <usrp_rx_stub.h> -#include "usrp_tx.h" -#include "usrp_standard.h" -#include <stdio.h> -#include <usrp_dbid.h> - -typedef usrp_inband_usb_packet transport_pkt; - -#include <symbols_usrp_interface_cs.h> -#include <symbols_usrp_tx_cs.h> -#include <symbols_usrp_rx_cs.h> -static pmt_t s_shutdown = pmt_intern("%shutdown"); - -static const bool verbose = false; - - -/*! - * \brief Initializes the USB interface m-block. - * - * The \p user_arg should be a PMT dictionary which can contain optional - * arguments for the block, such as the decimatoin and interpolation rate. - */ -usrp_usb_interface::usrp_usb_interface(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg) - : mb_mblock(rt, instance_name, user_arg), - d_fake_usrp(false), - d_rx_reading(false), - d_interp_tx(128), - d_decim_rx(128), - d_rf_freq(-1), - d_rbf("inband_tx_rx.rbf") -{ - // Dictionary for arguments to all of the components - pmt_t usrp_dict = user_arg; - - // Default TX/RX interface - std::string tx_interface = "usrp_tx"; - std::string rx_interface = "usrp_rx"; - - if (pmt_is_dict(usrp_dict)) { - - // The 'fake-usrp' key enables the TX and RX stubs if PMT_T - if(pmt_t fake_usrp = pmt_dict_ref(usrp_dict, - pmt_intern("fake-usrp"), - PMT_NIL)) { - if(pmt_eqv(fake_usrp, PMT_T)) { - tx_interface = "usrp_tx_stub"; - rx_interface = "usrp_rx_stub"; - d_fake_usrp=true; - } - } - - // Read the TX interpolations - if(pmt_t interp_tx = pmt_dict_ref(usrp_dict, - pmt_intern("interp-tx"), - PMT_NIL)) { - if(!pmt_eqv(interp_tx, PMT_NIL)) - d_interp_tx = pmt_to_long(interp_tx); - } - - // Read the RX decimation rate - if(pmt_t decim_rx = pmt_dict_ref(usrp_dict, - pmt_intern("decim-rx"), - PMT_NIL)) { - if(!pmt_eqv(decim_rx, PMT_NIL)) - d_decim_rx = pmt_to_long(decim_rx); - } - - // Read the RBF - if(pmt_t rbf = pmt_dict_ref(usrp_dict, - pmt_intern("rbf"), - PMT_NIL)) { - if(!pmt_eqv(rbf, PMT_NIL)) - d_rbf = pmt_symbol_to_string(rbf); - } - - // The RF center frequency - if(pmt_t rf_freq = pmt_dict_ref(usrp_dict, - pmt_intern("rf-freq"), - PMT_NIL)) { - if(!pmt_eqv(rf_freq, PMT_NIL)) - d_rf_freq = pmt_to_double(rf_freq); - } - } - - if (verbose) { - std::cout << "[USRP_USB_INTERFACE] Setting USRP RBF to " - << d_rbf << std::endl; - - std::cout << "[USRP_USB_INTERFACE] Setting TX interpolation to " - << d_interp_tx << std::endl; - - std::cout << "[USRP_USB_INTERFACE] Setting RX interpolation to " - << d_decim_rx << std::endl; - - std::cout << "[USRP_USB_INTERFACE] Using TX interface: " - << tx_interface << "\n"; - - std::cout << "[USRP_USB_INTERFACE] Using RX interface: " - << rx_interface << "\n"; - - } - - d_cs = define_port("cs", "usrp-interface-cs", true, mb_port::EXTERNAL); - d_rx_cs = define_port("rx_cs", "usrp-rx-cs", false, mb_port::INTERNAL); - d_tx_cs = define_port("tx_cs", "usrp-tx-cs", false, mb_port::INTERNAL); - - // Connect to TX and RX - define_component("tx", tx_interface, usrp_dict); - define_component("rx", rx_interface, usrp_dict); - connect("self", "rx_cs", "rx", "cs"); - connect("self", "tx_cs", "tx", "cs"); - - // FIXME: the code should query the FPGA to retrieve the number of channels and such - d_ntx_chan = 2; - d_nrx_chan = 2; -} - -usrp_usb_interface::~usrp_usb_interface() -{ - -} - -void -usrp_usb_interface::initial_transition() -{ - -} - -/*! - * \brief Handles all incoming signals to the block from the lowest m-blocks - * which read/write to the bus, or the higher m-block which is the USRP server. - */ -void -usrp_usb_interface::handle_message(mb_message_sptr msg) -{ - pmt_t event = msg->signal(); // the "name" of the message - pmt_t port_id = msg->port_id(); // which port it came in on - pmt_t data = msg->data(); - pmt_t invocation_handle; - - if (pmt_eq(event, s_shutdown)) // ignore (for now) - return; - - //------------- CONTROL / STATUS -------------// - if (pmt_eq(port_id, d_cs->port_symbol())) { - - //------------ OPEN --------------// - if (pmt_eq(event, s_cmd_usrp_open)){ - handle_cmd_open(data); - return; - } - //----------- CLOSE -------------// - else if (pmt_eq(event, s_cmd_usrp_close)) { - handle_cmd_close(data); - return; - } - //---------- NTX CHAN ----------// - else if (pmt_eq(event, s_cmd_usrp_ntx_chan)) { - invocation_handle = pmt_nth(0, data); - d_cs->send(s_response_usrp_ntx_chan, - pmt_list2(invocation_handle, - pmt_from_long(d_ntx_chan))); - return; - } - //---------- NRX CHAN ----------// - else if (pmt_eq(event, s_cmd_usrp_nrx_chan)) { - invocation_handle = pmt_nth(0, data); - d_cs->send(s_response_usrp_nrx_chan, - pmt_list2(invocation_handle, - pmt_from_long(d_nrx_chan))); - return; - } - //------------ WRITE -----------// - else if(pmt_eq(event, s_cmd_usrp_write)) { - handle_cmd_write(data); - return; - } - //-------- START READING --------// - else if(pmt_eq(event, s_cmd_usrp_start_reading)) { - handle_cmd_start_reading(data); - return; - } - //-------- STOP READING --------// - else if(pmt_eq(event, s_cmd_usrp_stop_reading)) { - handle_cmd_stop_reading(data); - return; - } - - goto unhandled; - } - - //---------------- RX ------------------// - if (pmt_eq(port_id, d_rx_cs->port_symbol())) { - - // Relay reads back up - if(pmt_eq(event, s_response_usrp_rx_read)) { - d_cs->send(s_response_usrp_read, data); - return; - } - - goto unhandled; - } - - //---------------- TX ------------------// - if (pmt_eq(port_id, d_tx_cs->port_symbol())) { - - if(pmt_eq(event, s_response_usrp_tx_write)) { - - pmt_t invocation_handle = pmt_nth(0, data); - pmt_t status = pmt_nth(1, data); - pmt_t channel = pmt_nth(2, data); - - d_cs->send(s_response_usrp_write, - pmt_list3(invocation_handle, - status, - channel)); - - return; - } - - goto unhandled; - } - - unhandled: - std::cout << "[USRP_USB_INTERFACE] unhandled msg: " << msg << std::endl; -} - -/*! - * \brief Called by the handle_message() method when the incoming signal is to - * open a USB connection to the USRP (cmd-usrp-open). - * - * The \p data parameter is a PMT list, where the elements are an invocation - * handle and the USRP number. - */ -void -usrp_usb_interface::handle_cmd_open(pmt_t data) -{ - pmt_t invocation_handle = pmt_nth(0, data); - long which_usrp = pmt_to_long(pmt_nth(1, data)); - pmt_t reply_data; - - if(d_fake_usrp) { - d_cs->send(s_response_usrp_open, pmt_list2(invocation_handle, PMT_T)); - return; - } - - if (verbose) - std::cout << "[USRP_USB_INTERFACE] Handling open request for USRP " << which_usrp << "\n"; - - // Open up a standard RX and TX for communication with the USRP - - d_utx = usrp_standard_tx::make(which_usrp, - d_interp_tx, - 1, // 1 channel - -1, // mux - 4096, // USB block size - 16, // nblocks for async transfers - d_rbf - ); - - if(d_utx==0) { - if (verbose) - std::cout << "[USRP_USB_INTERFACE] Failed to open TX\n"; - reply_data = pmt_list2(invocation_handle, PMT_F); - d_cs->send(s_response_usrp_open, reply_data); - return; - } - - // Perform TX daughterboard tuning - double target_freq; - unsigned int mux; - int tgain, rgain; - float input_rate; - bool ok; - usrp_tune_result r; - - // Cast to usrp_basic and then detect daughterboards - d_ub_tx = d_utx; - usrp_subdev_spec tspec = pick_tx_subdevice(); - db_base_sptr tsubdev = d_ub_tx->selected_subdev(tspec); - - // Set the TX mux value - mux = d_utx->determine_tx_mux_value(tspec); - d_utx->set_mux(mux); - - // Set the TX gain and determine rate - tgain = tsubdev->gain_max(); - tsubdev->set_gain(tgain); - input_rate = d_ub_tx->converter_rate() / d_utx->interp_rate(); - - // Perform the actual tuning, if no frequency specified then pick - if(d_rf_freq==-1) - target_freq = tsubdev->freq_min()+((tsubdev->freq_max()-tsubdev->freq_min())/2.0); - else - target_freq = d_rf_freq; - ok = d_utx->tune(tsubdev->which(), tsubdev, target_freq, &r); - tsubdev->set_enable(true); - - if(verbose) { - printf("TX Subdevice name is %s\n", tsubdev->name().c_str()); - printf("TX Subdevice freq range: (%g, %g)\n", - tsubdev->freq_min(), tsubdev->freq_max()); - printf("mux: %#08x\n", mux); - printf("target_freq: %f\n", target_freq); - printf("ok: %s\n", ok ? "true" : "false"); - printf("gain: %d\n", tgain); - printf("r.baseband_freq: %f\n", r.baseband_freq); - printf("r.dxc_freq: %f\n", r.dxc_freq); - printf("r.residual_freq: %f\n", r.residual_freq); - printf("r.inverted: %d\n", r.inverted); - } - - if(!ok) { - std::cerr << "[USRP_USB_INTERFACE] Failed to set center frequency on TX\n"; - reply_data = pmt_list2(invocation_handle, PMT_F); - d_cs->send(s_response_usrp_open, reply_data); - return; - } - - d_utx->start(); - - if (verbose) - std::cout << "[USRP_USB_INTERFACE] Setup TX channel\n"; - - d_urx = - usrp_standard_rx::make (which_usrp, - d_decim_rx, - 1, // nchan - -1, // mux - 0, // set blank mode to start - 4096, // USB block size - 16, // number of blocks for async transfers - d_rbf); - - if(!d_urx) { - if (verbose) - std::cout << "[usrp_server] Failed to open RX\n"; - reply_data = pmt_list2(invocation_handle, PMT_F); - d_cs->send(s_response_usrp_open, reply_data); - return; - } - - // Cast to usrp_basic and then detect daughterboards - d_ub_rx = d_urx; - usrp_subdev_spec rspec = pick_rx_subdevice(); - db_base_sptr rsubdev = d_ub_rx->selected_subdev(rspec); - - // Set the RX mux value - mux = d_urx->determine_rx_mux_value(rspec); - d_urx->set_mux(mux); - - // Set the RX gain and determine rate - rgain = rsubdev->gain_max()/2.0; - rsubdev->set_gain(rgain); - input_rate = d_ub_rx->converter_rate() / d_urx->decim_rate(); - - ok = d_urx->tune(rsubdev->which(), rsubdev, target_freq, &r); - rsubdev->set_enable(true); - - if(verbose) { - printf("RX Subdevice name is %s\n", rsubdev->name().c_str()); - printf("RX Subdevice freq range: (%g, %g)\n", - rsubdev->freq_min(), rsubdev->freq_max()); - printf("mux: %#08x\n", mux); - printf("target_freq: %f\n", target_freq); - printf("ok: %s\n", ok ? "true" : "false"); - printf("gain: %d\n", rgain); - printf("r.baseband_freq: %f\n", r.baseband_freq); - printf("r.dxc_freq: %f\n", r.dxc_freq); - printf("r.residual_freq: %f\n", r.residual_freq); - printf("r.inverted: %d\n", r.inverted); - } - - if(!ok) { - std::cerr << "[USRP_USB_INTERFACE] Failed to set center frequency on RX\n"; - reply_data = pmt_list2(invocation_handle, PMT_F); - d_cs->send(s_response_usrp_open, reply_data); - return; - } - - if (verbose) - std::cout << "[USRP_USB_INTERFACE] Setup RX channel\n"; - -// d_utx->_write_fpga_reg(FR_DEBUG_EN,0xf); -// d_utx->_write_oe(0, 0xffff, 0xffff); -// d_urx->_write_oe(0, 0xffff, 0xffff); -// d_utx->_write_oe(1, 0xffff, 0xffff); -// d_urx->_write_oe(1, 0xffff, 0xffff); - - d_cs->send(s_response_usrp_open, pmt_list2(invocation_handle, PMT_T)); -} - -/*! - * \brief Called by the handle_message() method when the incoming signal is to - * write data to the USB bus (cmd-usrp-write). - * - * The \p data parameter is a PMT list containing 3 mandatory elements in the - * following order: an invocation handle, channel, and a uniform vector - * representation of the packets. - */ -void -usrp_usb_interface::handle_cmd_write(pmt_t data) -{ - pmt_t invocation_handle = pmt_nth(0, data); - pmt_t channel = pmt_nth(1, data); - pmt_t pkts = pmt_nth(2, data); - - pmt_t tx_handle = pmt_make_any(d_utx); - - d_tx_cs->send(s_cmd_usrp_tx_write, - pmt_list4(invocation_handle, - channel, - pkts, - tx_handle)); -} - -/*! - * \brief Called by the handle_message() method when the incoming signal is to - * start reading data from the USB bus (cmd-usrp-start-reading). - * - * The \p data parameter is a PMT list with a single element: an invocation - * handle which can be returned with the response. - */ -void -usrp_usb_interface::handle_cmd_start_reading(pmt_t data) -{ - pmt_t invocation_handle = pmt_nth(0, data); - - if(verbose) - std::cout << "[USRP_USB_INTERFACE] Starting RX...\n"; - - if(!d_fake_usrp) - d_urx->start(); - - pmt_t rx_handle = pmt_make_any(d_urx); - - d_rx_cs->send(s_cmd_usrp_rx_start_reading, pmt_list2(PMT_NIL, rx_handle)); - - d_rx_reading = true; - - return; -} - -/*! - * \brief Called by the handle_message() method when the incoming signal is to - * stop reading data from the USB bus (cmd-usrp-stop-reading). - * - * The \p data parameter is a PMT list with a single element: an invocation - * handle which can be returned with the response. - */ -void -usrp_usb_interface::handle_cmd_stop_reading(pmt_t data) -{ - pmt_t invocation_handle = pmt_nth(0, data); - - if(!d_fake_usrp) { - if(verbose) - std::cout << "[USRP_USB_INTERFACE] Stopping RX...\n"; - usrp_rx_stop = true; - - // Used to allow a read() being called by a lower layer to complete before - // stopping, else there can be partial data left on the bus and can generate - // errors. - while(usrp_rx_stop) {usleep(1);} - d_urx->stop(); - } - else { - if(verbose) - std::cout << "[USRP_USB_INTERFACE] Stopping fake RX...\n"; - usrp_rx_stop_stub = true; // extern to communicate with stub to wait - } - - d_rx_reading = false; - - return; -} - -/*! - * \brief Called by the handle_message() method when the incoming signal is to - * close the USB connection to the USRP. - * - * The \p data parameter is a PMT list with a single element: an invocation - * handle which can be returned with the response. - */ -void -usrp_usb_interface::handle_cmd_close(pmt_t data) -{ - pmt_t invocation_handle = pmt_nth(0, data); - - if(d_rx_reading) - handle_cmd_stop_reading(PMT_NIL); - - if(d_fake_usrp) { - d_cs->send(s_response_usrp_close, pmt_list2(invocation_handle, PMT_T)); - return; - } - - if (verbose) - std::cout << "[USRP_USB_INTERFACE] Handling close request for USRP\n"; - - d_utx.reset(); - d_urx.reset(); - - d_cs->send(s_response_usrp_close, pmt_list2(invocation_handle, PMT_T)); - - // FIXME This seems like a _very_ strange place to be calling shutdown_all. - // That decision should be left to high-level code, not low-level code like this. - shutdown_all(PMT_T); -} - -usrp_subdev_spec -usrp_usb_interface::pick_rx_subdevice() -{ - int dbids[] = { - USRP_DBID_FLEX_400_RX, - USRP_DBID_FLEX_900_RX, - USRP_DBID_FLEX_1200_RX, - USRP_DBID_FLEX_2400_RX, - USRP_DBID_TV_RX, - USRP_DBID_TV_RX_REV_2, - USRP_DBID_DBS_RX, - USRP_DBID_BASIC_RX - }; - - std::vector<int> candidates(dbids, dbids+(sizeof(dbids)/sizeof(int))); - return pick_subdev(d_ub_rx, candidates); -} - -usrp_subdev_spec -usrp_usb_interface::pick_tx_subdevice() -{ - int dbids[] = { - USRP_DBID_FLEX_400_TX, - USRP_DBID_FLEX_900_TX, - USRP_DBID_FLEX_1200_TX, - USRP_DBID_FLEX_2400_TX, - USRP_DBID_BASIC_TX - }; - - std::vector<int> candidates(dbids, dbids+(sizeof(dbids)/sizeof(int))); - return pick_subdev(d_ub_tx, candidates); -} - -usrp_subdev_spec -usrp_usb_interface::pick_subdev(boost::shared_ptr<usrp_basic> d_usrp_basic, std::vector<int> candidates) -{ - int dbid0 = d_usrp_basic->selected_subdev(usrp_subdev_spec(0, 0))->dbid(); - int dbid1 = d_usrp_basic->selected_subdev(usrp_subdev_spec(1, 0))->dbid(); - - for (int i = 0; i < candidates.size(); i++) { - int dbid = candidates[i]; - if (dbid0 == dbid) - return usrp_subdev_spec(0, 0); - if (dbid1 == dbid) - return usrp_subdev_spec(1, 0); - } - - if (dbid0 >= 0) - return usrp_subdev_spec(0, 0); - if (dbid1 >= 0) - return usrp_subdev_spec(1, 0); - - throw std::runtime_error("No suitable daughterboard found!"); -} - - -REGISTER_MBLOCK_CLASS(usrp_usb_interface); diff --git a/usrp/limbo/inband/usrp_usb_interface.h b/usrp/limbo/inband/usrp_usb_interface.h deleted file mode 100644 index 4d7750a7d..000000000 --- a/usrp/limbo/inband/usrp_usb_interface.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef INCLUDED_USRP_USB_INTERFACE_H -#define INCLUDED_USRP_USB_INTERFACE_H - -#include <mblock/mblock.h> -#include <vector> -#include "usrp_standard.h" - -/*! - * \brief Implements the low level usb interface to the USRP - */ -class usrp_usb_interface : public mb_mblock -{ - public: - - usrp_standard_tx_sptr d_utx; - usrp_standard_rx_sptr d_urx; - - boost::shared_ptr<usrp_basic> d_ub_tx; - boost::shared_ptr<usrp_basic> d_ub_rx; - - mb_port_sptr d_cs; - mb_port_sptr d_rx_cs; - mb_port_sptr d_tx_cs; - - long d_ntx_chan; - long d_nrx_chan; - - bool d_fake_usrp; - - bool d_rx_reading; - - long d_interp_tx; - long d_decim_rx; - - double d_rf_freq; - - std::string d_rbf; - - public: - usrp_usb_interface(mb_runtime *rt, const std::string &instance_name, pmt_t user_arg); - ~usrp_usb_interface(); - void initial_transition(); - void handle_message(mb_message_sptr msg); - usrp_subdev_spec pick_rx_subdevice(); - usrp_subdev_spec pick_tx_subdevice(); - usrp_subdev_spec pick_subdev(boost::shared_ptr<usrp_basic> d_usrp_basic, std::vector<int> candidates); - - private: - void handle_cmd_open(pmt_t data); - void handle_cmd_close(pmt_t data); - void handle_cmd_write(pmt_t data); - void handle_cmd_start_reading(pmt_t data); - void handle_cmd_stop_reading(pmt_t data); - -}; - - -#endif /* INCLUDED_USRP_USB_INTERFACE_H */ diff --git a/usrp/usrp.pc.in b/usrp/usrp.pc.in index 2a15a05fd..d4794aa6f 100644 --- a/usrp/usrp.pc.in +++ b/usrp/usrp.pc.in @@ -5,7 +5,7 @@ includedir=@includedir@ Name: usrp Description: USRP Client Side C++ interface -Requires: @LIBUSB_PKG_CONFIG_NAME@ @usrp_darwin_omnithread_pc_requires@ +Requires: @LIBUSB_PKG_CONFIG_NAME@ Version: @VERSION@ Libs: -L${libdir} -lusrp Cflags: -I${includedir} |