diff options
author | Josh Blum <josh@joshknows.com> | 2010-02-19 16:22:25 -0800 |
---|---|---|
committer | Josh Blum <josh@joshknows.com> | 2010-02-19 16:22:25 -0800 |
commit | ea9d55b17b181495b4217c222bbf1b77519a802e (patch) | |
tree | e66e7fb9f311b46b4e66a9949b625041e9691c29 | |
parent | 186468252d9435ccd4f0d26a1a50dcaff1c6d4ed (diff) | |
download | uhd-ea9d55b17b181495b4217c222bbf1b77519a802e.tar.gz uhd-ea9d55b17b181495b4217c222bbf1b77519a802e.tar.bz2 uhd-ea9d55b17b181495b4217c222bbf1b77519a802e.zip |
DUC and DDC control packets OTW
-rw-r--r-- | firmware/microblaze/apps/txrx.c | 55 | ||||
-rw-r--r-- | host/include/uhd/props.hpp | 18 | ||||
-rw-r--r-- | host/lib/usrp/mboard/usrp2/dboard_impl.cpp | 1 | ||||
-rw-r--r-- | host/lib/usrp/mboard/usrp2/dsp_impl.cpp | 96 | ||||
-rw-r--r-- | host/lib/usrp/mboard/usrp2/fw_common.h | 21 | ||||
-rw-r--r-- | host/lib/usrp/mboard/usrp2/mboard_impl.cpp | 1 | ||||
-rw-r--r-- | host/lib/usrp/mboard/usrp2/usrp2_impl.cpp | 7 | ||||
-rw-r--r-- | host/lib/usrp/mboard/usrp2/usrp2_impl.hpp | 19 |
8 files changed, 169 insertions, 49 deletions
diff --git a/firmware/microblaze/apps/txrx.c b/firmware/microblaze/apps/txrx.c index bc8598768..686fda2fd 100644 --- a/firmware/microblaze/apps/txrx.c +++ b/firmware/microblaze/apps/txrx.c @@ -386,6 +386,61 @@ void handle_udp_ctrl_packet( ctrl_data_out.id = USRP2_CTRL_ID_DONE_WITH_THAT_AUX_ADC_DUDE; break; + /******************************************************************* + * DDC + ******************************************************************/ + case USRP2_CTRL_ID_SETUP_THIS_DDC_FOR_ME_BRO: + dsp_rx_regs->freq = ctrl_data_in->data.ddc_args.freq_word; + + //setup the interp and half band filters + { + uint32_t decim = ctrl_data_in->data.ddc_args.decim; + uint32_t hb1 = 0; + uint32_t hb2 = 0; + if (!(decim & 1)){ + hb2 = 1; + decim = decim >> 1; + } + if (!(decim & 1)){ + hb1 = 1; + decim = decim >> 1; + } + uint32_t decim_word = (hb1<<9) | (hb2<<8) | decim; + dsp_rx_regs->decim_rate = decim_word; + printf("Decim: %d, register %d\n", ctrl_data_in->data.ddc_args.decim, decim_word); + } + + ctrl_data_out.id = USRP2_CTRL_ID_TOTALLY_SETUP_THE_DDC_DUDE; + break; + + /******************************************************************* + * DUC + ******************************************************************/ + case USRP2_CTRL_ID_SETUP_THIS_DUC_FOR_ME_BRO: + dsp_tx_regs->freq = ctrl_data_in->data.duc_args.freq_word; + dsp_tx_regs->scale_iq = ctrl_data_in->data.duc_args.scale_iq; + + //setup the interp and half band filters + { + uint32_t interp = ctrl_data_in->data.duc_args.interp; + uint32_t hb1 = 0; + uint32_t hb2 = 0; + if (!(interp & 1)){ + hb2 = 1; + interp = interp >> 1; + } + if (!(interp & 1)){ + hb1 = 1; + interp = interp >> 1; + } + uint32_t interp_word = (hb1<<9) | (hb2<<8) | interp; + dsp_tx_regs->interp_rate = interp_word; + printf("Interp: %d, register %d\n", ctrl_data_in->data.duc_args.interp, interp_word); + } + + ctrl_data_out.id = USRP2_CTRL_ID_TOTALLY_SETUP_THE_DUC_DUDE; + break; + default: ctrl_data_out.id = USRP2_CTRL_ID_HUH_WHAT; diff --git a/host/include/uhd/props.hpp b/host/include/uhd/props.hpp index 4012ffbd2..2b6daf6c5 100644 --- a/host/include/uhd/props.hpp +++ b/host/include/uhd/props.hpp @@ -30,15 +30,15 @@ namespace uhd{ typedef float gain_t; typedef double freq_t; - //scalar types - typedef int int_scalar_t; - typedef float real_scalar_t; - typedef std::complex<real_scalar_t> complex_scalar_t; - - //vector types - typedef std::vector<int_scalar_t> int_vec_t; - typedef std::vector<real_scalar_t> real_vec_t; - typedef std::vector<complex_scalar_t> complex_vec_t; + //scalar types (have not used yet, dont uncomment until needed) + //typedef int int_scalar_t; + //typedef float real_scalar_t; + //typedef std::complex<real_scalar_t> complex_scalar_t; + + //vector types (have not used yet, dont uncomment until needed) + //typedef std::vector<int_scalar_t> int_vec_t; + //typedef std::vector<real_scalar_t> real_vec_t; + //typedef std::vector<complex_scalar_t> complex_vec_t; //typedef for handling named properties typedef std::vector<std::string> prop_names_t; diff --git a/host/lib/usrp/mboard/usrp2/dboard_impl.cpp b/host/lib/usrp/mboard/usrp2/dboard_impl.cpp index 7abce8e6a..d127c7f87 100644 --- a/host/lib/usrp/mboard/usrp2/dboard_impl.cpp +++ b/host/lib/usrp/mboard/usrp2/dboard_impl.cpp @@ -16,7 +16,6 @@ // #include <uhd/utils.hpp> -#include <uhd/props.hpp> #include "usrp2_impl.hpp" #include "dboard_interface.hpp" diff --git a/host/lib/usrp/mboard/usrp2/dsp_impl.cpp b/host/lib/usrp/mboard/usrp2/dsp_impl.cpp index 7c31a5e3a..a1c96adab 100644 --- a/host/lib/usrp/mboard/usrp2/dsp_impl.cpp +++ b/host/lib/usrp/mboard/usrp2/dsp_impl.cpp @@ -16,7 +16,6 @@ // #include <uhd/utils.hpp> -#include <uhd/props.hpp> #include <boost/assign/list_of.hpp> #include "usrp2_impl.hpp" @@ -25,9 +24,22 @@ using namespace uhd; /*********************************************************************** * DDC Helper Methods **********************************************************************/ -void usrp2_impl::init_ddc_config(size_t which){ +static uint32_t calculate_freq_word_and_update_actual_freq(freq_t &freq, freq_t clock_freq){ + double scale_factor = pow(2.0, 32); + + //calculate the freq register word + uint32_t freq_word = rint((freq / clock_freq) * scale_factor); + + //update the actual frequency + freq = (double(freq_word) / scale_factor) * clock_freq; + + return freq_word; +} + +void usrp2_impl::init_ddc_config(void){ //load the allowed decim/interp rates //_USRP2_RATES = range(4, 128+1, 1) + range(130, 256+1, 2) + range(260, 512+1, 4) + _allowed_decim_and_interp_rates.clear(); for (size_t i = 4; i <= 128; i+=1){ _allowed_decim_and_interp_rates.push_back(i); } @@ -39,30 +51,41 @@ void usrp2_impl::init_ddc_config(size_t which){ } //create the ddc in the rx dsp dict - _rx_dsps[str(boost::format("ddc%d") % which)] = wax_obj_proxy( - boost::bind(&usrp2_impl::ddc_get, this, _1, _2, which), - boost::bind(&usrp2_impl::ddc_set, this, _1, _2, which) + _rx_dsps["ddc0"] = wax_obj_proxy( + boost::bind(&usrp2_impl::ddc_get, this, _1, _2), + boost::bind(&usrp2_impl::ddc_set, this, _1, _2) ); //initial config and update - _ddc_decim[which] = 16; - _ddc_freq[which] = 0; - update_ddc_config(which); + _ddc_decim = 16; + _ddc_freq = 0; + _ddc_enabled = false; + update_ddc_config(); } -void usrp2_impl::update_ddc_config(size_t){ - //TODO send it! +void usrp2_impl::update_ddc_config(void){ + //setup the out data + usrp2_ctrl_data_t out_data; + out_data.id = htonl(USRP2_CTRL_ID_SETUP_THIS_DDC_FOR_ME_BRO); + out_data.data.ddc_args.freq_word = htonl( + calculate_freq_word_and_update_actual_freq(_ddc_freq, get_master_clock_freq()) + ); + out_data.data.ddc_args.decim = htonl(_ddc_decim); + + //send and recv + usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data); + ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_TOTALLY_SETUP_THE_DDC_DUDE); } /*********************************************************************** * DDC Properties **********************************************************************/ -void usrp2_impl::ddc_get(const wax::obj &key, wax::obj &val, size_t which){ +void usrp2_impl::ddc_get(const wax::obj &key, wax::obj &val){ //handle the case where the key is an expected dsp property if (key.type() == typeid(dsp_prop_t)){ switch(wax::cast<dsp_prop_t>(key)){ case DSP_PROP_NAME: - val = str(boost::format("usrp2 ddc%d") % which); + val = std::string("usrp2 ddc0"); return; case DSP_PROP_OTHERS:{ @@ -71,6 +94,8 @@ void usrp2_impl::ddc_get(const wax::obj &key, wax::obj &val, size_t which){ ("decim") ("decim_rates") ("freq") + ("enabled") + //TODO ("stream_at") ; val = others; } @@ -85,7 +110,7 @@ void usrp2_impl::ddc_get(const wax::obj &key, wax::obj &val, size_t which){ return; } else if (key_name == "decim"){ - val = _ddc_decim[which]; + val = _ddc_decim; return; } else if (key_name == "decim_rates"){ @@ -93,7 +118,11 @@ void usrp2_impl::ddc_get(const wax::obj &key, wax::obj &val, size_t which){ return; } else if (key_name == "freq"){ - val = _ddc_freq[which]; + val = _ddc_freq; + return; + } + else if (key_name == "enabled"){ + val = _ddc_enabled; return; } @@ -102,7 +131,7 @@ void usrp2_impl::ddc_get(const wax::obj &key, wax::obj &val, size_t which){ )); } -void usrp2_impl::ddc_set(const wax::obj &key, const wax::obj &val, size_t which){ +void usrp2_impl::ddc_set(const wax::obj &key, const wax::obj &val){ //handle string-based properties specific to this dsp std::string key_name = wax::cast<std::string>(key); if (key_name == "decim"){ @@ -112,16 +141,22 @@ void usrp2_impl::ddc_set(const wax::obj &key, const wax::obj &val, size_t which) _allowed_decim_and_interp_rates.end(), new_decim )); - _ddc_decim[which] = new_decim; //shadow - update_ddc_config(which); + _ddc_decim = new_decim; //shadow + update_ddc_config(); return; } else if (key_name == "freq"){ freq_t new_freq = wax::cast<freq_t>(val); ASSERT_THROW(new_freq <= get_master_clock_freq()/2.0); ASSERT_THROW(new_freq >= -get_master_clock_freq()/2.0); - _ddc_freq[which] = new_freq; //shadow - update_ddc_config(which); + _ddc_freq = new_freq; //shadow + update_ddc_config(); + return; + } + else if (key_name == "enabled"){ + bool new_enabled = wax::cast<bool>(val); + _ddc_enabled = new_enabled; //shadow + //update_ddc_config(); TODO separate update return; } @@ -135,7 +170,7 @@ void usrp2_impl::ddc_set(const wax::obj &key, const wax::obj &val, size_t which) **********************************************************************/ void usrp2_impl::init_duc_config(void){ //create the duc in the tx dsp dict - _tx_dsps[str(boost::format("duc%d") % 0)] = wax_obj_proxy( + _tx_dsps["duc0"] = wax_obj_proxy( boost::bind(&usrp2_impl::duc_get, this, _1, _2), boost::bind(&usrp2_impl::duc_set, this, _1, _2) ); @@ -148,14 +183,25 @@ void usrp2_impl::init_duc_config(void){ void usrp2_impl::update_duc_config(void){ // Calculate CIC interpolation (i.e., without halfband interpolators) - size_t interp = 0; //TODO - while(interp > 128) interp /= 2; + size_t tmp_interp = _duc_interp; + while(tmp_interp > 128) tmp_interp /= 2; // Calculate closest multiplier constant to reverse gain absent scale multipliers - size_t interp_cubed = pow(interp, 3); + size_t interp_cubed = pow(tmp_interp, 3); size_t scale = rint((4096*pow(2, ceil(log2(interp_cubed))))/(1.65*interp_cubed)); - //TODO send it! + //setup the out data + usrp2_ctrl_data_t out_data; + out_data.id = htonl(USRP2_CTRL_ID_SETUP_THIS_DUC_FOR_ME_BRO); + out_data.data.duc_args.freq_word = htonl( + calculate_freq_word_and_update_actual_freq(_duc_freq, get_master_clock_freq()) + ); + out_data.data.duc_args.interp = htonl(_duc_interp); + out_data.data.duc_args.scale_iq = htonl(scale); + + //send and recv + usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data); + ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_TOTALLY_SETUP_THE_DUC_DUDE); } /*********************************************************************** @@ -166,7 +212,7 @@ void usrp2_impl::duc_get(const wax::obj &key, wax::obj &val){ if (key.type() == typeid(dsp_prop_t)){ switch(wax::cast<dsp_prop_t>(key)){ case DSP_PROP_NAME: - val = str(boost::format("usrp2 duc%d") % 0); + val = std::string("usrp2 duc0"); return; case DSP_PROP_OTHERS:{ diff --git a/host/lib/usrp/mboard/usrp2/fw_common.h b/host/lib/usrp/mboard/usrp2/fw_common.h index ede19d45f..d3ffbf7d5 100644 --- a/host/lib/usrp/mboard/usrp2/fw_common.h +++ b/host/lib/usrp/mboard/usrp2/fw_common.h @@ -78,6 +78,12 @@ typedef enum{ USRP2_CTRL_ID_READ_FROM_THIS_AUX_ADC_BRO, USRP2_CTRL_ID_DONE_WITH_THAT_AUX_ADC_DUDE, + USRP2_CTRL_ID_SETUP_THIS_DDC_FOR_ME_BRO, + USRP2_CTRL_ID_TOTALLY_SETUP_THE_DDC_DUDE, + + USRP2_CTRL_ID_SETUP_THIS_DUC_FOR_ME_BRO, + USRP2_CTRL_ID_TOTALLY_SETUP_THE_DUC_DUDE, + USRP2_CTRL_ID_PEACE_OUT } usrp2_ctrl_id_t; @@ -156,6 +162,21 @@ typedef struct{ uint8_t _pad[2]; uint32_t value; } aux_args; + struct { + uint32_t freq_word; + uint32_t decim; + } ddc_args; + struct { + uint8_t enabled; + uint8_t _pad[3]; + uint32_t secs; + uint32_t ticks; + } streaming; + struct { + uint32_t freq_word; + uint32_t interp; + uint32_t scale_iq; + } duc_args; } data; } usrp2_ctrl_data_t; diff --git a/host/lib/usrp/mboard/usrp2/mboard_impl.cpp b/host/lib/usrp/mboard/usrp2/mboard_impl.cpp index 0dec3a473..2e4a0715f 100644 --- a/host/lib/usrp/mboard/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/mboard/usrp2/mboard_impl.cpp @@ -16,7 +16,6 @@ // #include <uhd/utils.hpp> -#include <uhd/props.hpp> #include "usrp2_impl.hpp" using namespace uhd; diff --git a/host/lib/usrp/mboard/usrp2/usrp2_impl.cpp b/host/lib/usrp/mboard/usrp2/usrp2_impl.cpp index 2bb1e9955..29732c3c0 100644 --- a/host/lib/usrp/mboard/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/mboard/usrp2/usrp2_impl.cpp @@ -19,7 +19,6 @@ #include <boost/format.hpp> #include <boost/bind.hpp> #include <uhd/utils.hpp> -#include <uhd/props.hpp> #include <iostream> #include "usrp2_impl.hpp" @@ -38,10 +37,8 @@ usrp2_impl::usrp2_impl( //init the tx and rx dboards dboard_init(); - //init the ddcs (however many we have) - for (size_t i = 0; i < _num_ddc; i++){ - init_ddc_config(i); - } + //init the ddc + init_ddc_config(); //init the duc init_duc_config(); diff --git a/host/lib/usrp/mboard/usrp2/usrp2_impl.hpp b/host/lib/usrp/mboard/usrp2/usrp2_impl.hpp index d2d90b8ed..638498a1c 100644 --- a/host/lib/usrp/mboard/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/mboard/usrp2/usrp2_impl.hpp @@ -16,6 +16,8 @@ // #include <uhd/dict.hpp> +#include <uhd/props.hpp> +#include <uhd/time_spec.hpp> #include <boost/thread.hpp> #include <boost/shared_ptr.hpp> #include <boost/function.hpp> @@ -129,21 +131,22 @@ private: //methods and shadows for the ddc dsp std::vector<size_t> _allowed_decim_and_interp_rates; - static const size_t _num_ddc = 1; - size_t _ddc_decim[_num_ddc]; - double _ddc_freq[_num_ddc]; - void init_ddc_config(size_t which); - void update_ddc_config(size_t which_ddc); + size_t _ddc_decim; + uhd::freq_t _ddc_freq; + bool _ddc_enabled; + //TODO uhd::time_spec_t _ddc_stream_at; + void init_ddc_config(void); + void update_ddc_config(void); //methods and shadows for the duc dsp size_t _duc_interp; - double _duc_freq; + uhd::freq_t _duc_freq; void init_duc_config(void); void update_duc_config(void); //properties interface for ddc - void ddc_get(const wax::obj &, wax::obj &, size_t which); - void ddc_set(const wax::obj &, const wax::obj &, size_t which); + void ddc_get(const wax::obj &, wax::obj &); + void ddc_set(const wax::obj &, const wax::obj &); uhd::dict<std::string, wax_obj_proxy> _rx_dsps; //properties interface for duc |