Revision 615af6ca host/lib/usrp/usrp_e100/dsp_impl.cpp

b/host/lib/usrp/usrp_e100/dsp_impl.cpp
22 22
#include <boost/math/special_functions/round.hpp>
23 23
#include <boost/bind.hpp>
24 24

  
25
#define rint boost::math::iround
26

  
27 25
using namespace uhd;
28 26
using namespace uhd::usrp;
29 27

  
30 28
/***********************************************************************
29
 * DSP impl and methods
30
 **********************************************************************/
31
struct usrp_e100_impl::dsp_impl{
32
    uhd::dict<size_t, size_t> ddc_decim;
33
    uhd::dict<size_t, double> ddc_freq;
34
    uhd::dict<size_t, size_t> duc_interp;
35
    uhd::dict<size_t, double> duc_freq;
36
};
37

  
38
/***********************************************************************
31 39
 * RX DDC Initialization
32 40
 **********************************************************************/
33
void usrp_e100_impl::rx_ddc_init(void){
34
    _rx_ddc_proxy = wax_obj_proxy::make(
35
        boost::bind(&usrp_e100_impl::rx_ddc_get, this, _1, _2),
36
        boost::bind(&usrp_e100_impl::rx_ddc_set, this, _1, _2)
37
    );
38

  
39
    //initial config and update
40
    rx_ddc_set(DSP_PROP_FREQ_SHIFT, double(0));
41
    rx_ddc_set(DSP_PROP_HOST_RATE, double(16e6));
41
void usrp_e100_impl::dsp_init(void){
42
    //create new dsp impl
43
    _dsp_impl = UHD_PIMPL_MAKE(dsp_impl, ());
44

  
45
    //bind and initialize the rx dsps
46
    for (size_t i = 0; i < E100_NUM_RX_DSPS; i++){
47
        _rx_dsp_proxies[str(boost::format("DSP%d")%i)] = wax_obj_proxy::make(
48
            boost::bind(&usrp_e100_impl::ddc_get, this, _1, _2, i),
49
            boost::bind(&usrp_e100_impl::ddc_set, this, _1, _2, i)
50
        );
51

  
52
        //initial config and update
53
        ddc_set(DSP_PROP_FREQ_SHIFT, double(0), i);
54
        ddc_set(DSP_PROP_HOST_RATE, double(_clock_ctrl->get_fpga_clock_rate()/16), i);
55

  
56
        //setup the rx control registers
57
        _iface->poke32(UE_REG_RX_CTRL_CLEAR(i), 1); //reset
58
        _iface->poke32(UE_REG_RX_CTRL_NSAMPS_PP(i), this->get_max_recv_samps_per_packet());
59
        _iface->poke32(UE_REG_RX_CTRL_NCHANNELS(i), 1);
60
        _iface->poke32(UE_REG_RX_CTRL_VRT_HDR(i), 0
61
            | (0x1 << 28) //if data with stream id
62
            | (0x1 << 26) //has trailer
63
            | (0x3 << 22) //integer time other
64
            | (0x1 << 20) //fractional time sample count
65
        );
66
        _iface->poke32(UE_REG_RX_CTRL_VRT_SID(i), E100_DSP_SID_BASE + i);
67
        _iface->poke32(UE_REG_RX_CTRL_VRT_TLR(i), 0);
68
        _iface->poke32(UE_REG_TIME64_TPS, size_t(_clock_ctrl->get_fpga_clock_rate()));
69
    }
70

  
71
    //bind and initialize the tx dsps
72
    for (size_t i = 0; i < E100_NUM_TX_DSPS; i++){
73
        _tx_dsp_proxies[str(boost::format("DSP%d")%i)] = wax_obj_proxy::make(
74
            boost::bind(&usrp_e100_impl::duc_get, this, _1, _2, i),
75
            boost::bind(&usrp_e100_impl::duc_set, this, _1, _2, i)
76
        );
77

  
78
        //initial config and update
79
        duc_set(DSP_PROP_FREQ_SHIFT, double(0), i);
80
        duc_set(DSP_PROP_HOST_RATE, double(_clock_ctrl->get_fpga_clock_rate()/16), i);
81

  
82
        //init the tx control registers
83
        _iface->poke32(UE_REG_TX_CTRL_CLEAR_STATE, 1); //reset
84
        _iface->poke32(UE_REG_TX_CTRL_NUM_CHAN, 0);    //1 channel
85
        _iface->poke32(UE_REG_TX_CTRL_REPORT_SID, E100_ASYNC_SID);
86
        _iface->poke32(UE_REG_TX_CTRL_POLICY, UE_FLAG_TX_CTRL_POLICY_NEXT_PACKET);
87
    }
42 88
}
43 89

  
44 90
/***********************************************************************
45 91
 * RX DDC Get
46 92
 **********************************************************************/
47
void usrp_e100_impl::rx_ddc_get(const wax::obj &key_, wax::obj &val){
93
void usrp_e100_impl::ddc_get(const wax::obj &key_, wax::obj &val, size_t which_dsp){
48 94
    named_prop_t key = named_prop_t::extract(key_);
49 95

  
50 96
    switch(key.as<dsp_prop_t>()){
51 97
    case DSP_PROP_NAME:
52
        val = std::string("usrp-e ddc0");
98
        val = str(boost::format("%s ddc%d") % _iface->get_cname() % which_dsp);
53 99
        return;
54 100

  
55 101
    case DSP_PROP_OTHERS:
......
57 103
        return;
58 104

  
59 105
    case DSP_PROP_FREQ_SHIFT:
60
        val = _ddc_freq;
106
        val = _dsp_impl->ddc_freq[which_dsp];
61 107
        return;
62 108

  
63 109
    case DSP_PROP_CODEC_RATE:
......
65 111
        return;
66 112

  
67 113
    case DSP_PROP_HOST_RATE:
68
        val = _clock_ctrl->get_fpga_clock_rate()/_ddc_decim;
114
        val = _clock_ctrl->get_fpga_clock_rate()/_dsp_impl->ddc_decim[which_dsp];
69 115
        return;
70 116

  
71 117
    default: UHD_THROW_PROP_GET_ERROR();
......
75 121
/***********************************************************************
76 122
 * RX DDC Set
77 123
 **********************************************************************/
78
void usrp_e100_impl::rx_ddc_set(const wax::obj &key_, const wax::obj &val){
124
void usrp_e100_impl::ddc_set(const wax::obj &key_, const wax::obj &val, size_t which_dsp){
79 125
    named_prop_t key = named_prop_t::extract(key_);
80 126

  
81 127
    switch(key.as<dsp_prop_t>()){
82 128

  
83 129
    case DSP_PROP_STREAM_CMD:
84
        issue_stream_cmd(val.as<stream_cmd_t>());
130
        issue_ddc_stream_cmd(val.as<stream_cmd_t>(), which_dsp);
85 131
        return;
86 132

  
87 133
    case DSP_PROP_FREQ_SHIFT:{
88 134
            double new_freq = val.as<double>();
89
            _iface->poke32(UE_REG_DSP_RX_FREQ,
135
            _iface->poke32(UE_REG_DSP_RX_FREQ(which_dsp),
90 136
                dsp_type1::calc_cordic_word_and_update(new_freq, _clock_ctrl->get_fpga_clock_rate())
91 137
            );
92
            _ddc_freq = new_freq; //shadow
138
            _dsp_impl->ddc_freq[which_dsp] = new_freq; //shadow
93 139
        }
94 140
        return;
95 141

  
96 142
    case DSP_PROP_HOST_RATE:{
97
            //set the decimation
98
            _ddc_decim = rint(_clock_ctrl->get_fpga_clock_rate()/val.as<double>());
99
            _iface->poke32(UE_REG_DSP_RX_DECIM_RATE, dsp_type1::calc_cic_filter_word(_ddc_decim));
143
            _dsp_impl->ddc_decim[which_dsp] = boost::math::iround(_clock_ctrl->get_fpga_clock_rate()/val.as<double>());
100 144

  
101
            //set the scaling
102
            static const boost::int16_t default_rx_scale_iq = 1024;
103
            _iface->poke32(UE_REG_DSP_RX_SCALE_IQ,
104
                dsp_type1::calc_iq_scale_word(default_rx_scale_iq, default_rx_scale_iq)
105
            );
145
            //set the decimation
146
            _iface->poke32(UE_REG_DSP_RX_DECIM(which_dsp), dsp_type1::calc_cic_filter_word(_dsp_impl->ddc_decim[which_dsp]));
106 147
        }
107 148
        this->update_xport_channel_mapping(); //rate changed -> update
108 149
        return;
......
112 153
}
113 154

  
114 155
/***********************************************************************
115
 * TX DUC Initialization
116
 **********************************************************************/
117
void usrp_e100_impl::tx_duc_init(void){
118
    _tx_duc_proxy = wax_obj_proxy::make(
119
        boost::bind(&usrp_e100_impl::tx_duc_get, this, _1, _2),
120
        boost::bind(&usrp_e100_impl::tx_duc_set, this, _1, _2)
121
    );
122

  
123
    //initial config and update
124
    tx_duc_set(DSP_PROP_FREQ_SHIFT, double(0));
125
    tx_duc_set(DSP_PROP_HOST_RATE, double(16e6));
126
}
127

  
128
/***********************************************************************
129 156
 * TX DUC Get
130 157
 **********************************************************************/
131
void usrp_e100_impl::tx_duc_get(const wax::obj &key_, wax::obj &val){
158
void usrp_e100_impl::duc_get(const wax::obj &key_, wax::obj &val, size_t which_dsp){
132 159
    named_prop_t key = named_prop_t::extract(key_);
133 160

  
134 161
    switch(key.as<dsp_prop_t>()){
135 162
    case DSP_PROP_NAME:
136
        val = std::string("usrp-e duc0");
163
        val = str(boost::format("%s duc%d") % _iface->get_cname() % which_dsp);
137 164
        return;
138 165

  
139 166
    case DSP_PROP_OTHERS:
......
141 168
        return;
142 169

  
143 170
    case DSP_PROP_FREQ_SHIFT:
144
        val = _duc_freq;
171
        val = _dsp_impl->duc_freq[which_dsp];
145 172
        return;
146 173

  
147 174
    case DSP_PROP_CODEC_RATE:
......
149 176
        return;
150 177

  
151 178
    case DSP_PROP_HOST_RATE:
152
        val = _clock_ctrl->get_fpga_clock_rate()/_duc_interp;
179
        val = _clock_ctrl->get_fpga_clock_rate()/_dsp_impl->duc_interp[which_dsp];
153 180
        return;
154 181

  
155 182
    default: UHD_THROW_PROP_GET_ERROR();
......
159 186
/***********************************************************************
160 187
 * TX DUC Set
161 188
 **********************************************************************/
162
void usrp_e100_impl::tx_duc_set(const wax::obj &key_, const wax::obj &val){
189
void usrp_e100_impl::duc_set(const wax::obj &key_, const wax::obj &val, size_t which_dsp){
163 190
    named_prop_t key = named_prop_t::extract(key_);
164 191

  
165 192
    switch(key.as<dsp_prop_t>()){
......
169 196
            _iface->poke32(UE_REG_DSP_TX_FREQ,
170 197
                dsp_type1::calc_cordic_word_and_update(new_freq, _clock_ctrl->get_fpga_clock_rate())
171 198
            );
172
            _duc_freq = new_freq; //shadow
199
            _dsp_impl->duc_freq[which_dsp] = new_freq; //shadow
173 200
        }
174 201
        return;
175 202

  
176 203
    case DSP_PROP_HOST_RATE:{
177
            _duc_interp = rint(_clock_ctrl->get_fpga_clock_rate()/val.as<double>());
204
            _dsp_impl->duc_interp[which_dsp] = boost::math::iround(_clock_ctrl->get_fpga_clock_rate()/val.as<double>());
178 205

  
179 206
            //set the interpolation
180
            _iface->poke32(UE_REG_DSP_TX_INTERP_RATE, dsp_type1::calc_cic_filter_word(_duc_interp));
207
            _iface->poke32(UE_REG_DSP_TX_INTERP_RATE, dsp_type1::calc_cic_filter_word(_dsp_impl->duc_interp[which_dsp]));
181 208

  
182 209
            //set the scaling
183
            _iface->poke32(UE_REG_DSP_TX_SCALE_IQ, dsp_type1::calc_iq_scale_word(_duc_interp));
210
            _iface->poke32(UE_REG_DSP_TX_SCALE_IQ, dsp_type1::calc_iq_scale_word(_dsp_impl->duc_interp[which_dsp]));
184 211
        }
185 212
        this->update_xport_channel_mapping(); //rate changed -> update
186 213
        return;

Also available in: Unified diff