summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-02-19 16:22:25 -0800
committerJosh Blum <josh@joshknows.com>2010-02-19 16:22:25 -0800
commitea9d55b17b181495b4217c222bbf1b77519a802e (patch)
treee66e7fb9f311b46b4e66a9949b625041e9691c29
parent186468252d9435ccd4f0d26a1a50dcaff1c6d4ed (diff)
downloaduhd-ea9d55b17b181495b4217c222bbf1b77519a802e.tar.gz
uhd-ea9d55b17b181495b4217c222bbf1b77519a802e.tar.bz2
uhd-ea9d55b17b181495b4217c222bbf1b77519a802e.zip
DUC and DDC control packets OTW
-rw-r--r--firmware/microblaze/apps/txrx.c55
-rw-r--r--host/include/uhd/props.hpp18
-rw-r--r--host/lib/usrp/mboard/usrp2/dboard_impl.cpp1
-rw-r--r--host/lib/usrp/mboard/usrp2/dsp_impl.cpp96
-rw-r--r--host/lib/usrp/mboard/usrp2/fw_common.h21
-rw-r--r--host/lib/usrp/mboard/usrp2/mboard_impl.cpp1
-rw-r--r--host/lib/usrp/mboard/usrp2/usrp2_impl.cpp7
-rw-r--r--host/lib/usrp/mboard/usrp2/usrp2_impl.hpp19
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