Statistics
| Branch: | Tag: | Revision:

root / host / lib / usrp / usrp1 / dboard_iface.cpp @ 9cb9e7d5

History | View | Annotate | Download (9.8 kB)

1
//
2
// Copyright 2010 Ettus Research LLC
3
//
4
// This program is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
//
17

    
18
#include "usrp1_iface.hpp"
19
#include "fpga_regs_common.h"
20
#include "usrp_spi_defs.h"
21
#include "clock_ctrl.hpp"
22
#include "codec_ctrl.hpp"
23
#include <uhd/usrp/dboard_iface.hpp>
24
#include <uhd/types/dict.hpp>
25
#include <uhd/utils/assert.hpp>
26
#include <boost/assign/list_of.hpp>
27
#include <iostream>
28

    
29
using namespace uhd;
30
using namespace uhd::usrp;
31
using namespace boost::assign;
32

    
33
class usrp1_dboard_iface : public dboard_iface {
34
public:
35

    
36
    usrp1_dboard_iface(usrp1_iface::sptr iface,
37
                       usrp1_clock_ctrl::sptr clock,
38
                       usrp1_codec_ctrl::sptr codec)
39
    {
40
        _iface = iface;
41
        _clock = clock;
42
        _codec = codec;
43

    
44
        //init the clock rate shadows
45
        this->set_clock_rate(UNIT_RX, _clock->get_master_clock_freq());
46
        this->set_clock_rate(UNIT_TX, _clock->get_master_clock_freq());
47
    }
48

    
49
    ~usrp1_dboard_iface()
50
    {
51
        /* NOP */
52
    }
53

    
54
    std::string get_mboard_name()
55
    {
56
        return "usrp1";
57
    }
58

    
59
    void write_aux_dac(unit_t, aux_dac_t, float);
60
    float read_aux_adc(unit_t, aux_adc_t);
61

    
62
    void set_pin_ctrl(unit_t, boost::uint16_t);
63
    void set_atr_reg(unit_t, atr_reg_t, boost::uint16_t);
64
    void set_gpio_ddr(unit_t, boost::uint16_t);
65
    void write_gpio(unit_t, boost::uint16_t);
66
    boost::uint16_t read_gpio(unit_t);
67

    
68
    void write_i2c(boost::uint8_t, const byte_vector_t &);
69
    byte_vector_t read_i2c(boost::uint8_t, size_t);
70

    
71
    void write_spi(unit_t unit,
72
                   const spi_config_t &config,
73
                   boost::uint32_t data,
74
                   size_t num_bits);
75

    
76
    boost::uint32_t read_write_spi(unit_t unit,
77
                                   const spi_config_t &config,
78
                                   boost::uint32_t data,
79
                                   size_t num_bits);
80

    
81
    void set_clock_rate(unit_t, double);
82
    std::vector<double> get_clock_rates(unit_t);
83
    double get_clock_rate(unit_t);
84
    void set_clock_enabled(unit_t, bool);
85

    
86
private:
87
    usrp1_iface::sptr _iface;
88
    usrp1_clock_ctrl::sptr _clock;
89
    usrp1_codec_ctrl::sptr _codec;
90
    uhd::dict<unit_t, double> _clock_rates;
91
};
92

    
93
/***********************************************************************
94
 * Make Function
95
 **********************************************************************/
96
dboard_iface::sptr make_usrp1_dboard_iface(usrp1_iface::sptr iface,
97
                                           usrp1_clock_ctrl::sptr clock,
98
                                           usrp1_codec_ctrl::sptr codec)
99
{
100
    return dboard_iface::sptr(new usrp1_dboard_iface(iface, clock, codec));
101
}
102

    
103
/***********************************************************************
104
 * Clock Rates
105
 **********************************************************************/
106
void usrp1_dboard_iface::set_clock_rate(unit_t unit, double rate)
107
{
108
    _clock_rates[unit] = rate;
109
    switch(unit) {
110
    case UNIT_RX: return _clock->set_rx_dboard_clock_rate(rate);    
111
    case UNIT_TX: return _clock->set_tx_dboard_clock_rate(rate);    
112
    }
113
}
114

    
115
/*
116
 * TODO: if this is a dbsrx return the rate of 4MHZ and set FPGA magic
117
 */
118
std::vector<double> usrp1_dboard_iface::get_clock_rates(unit_t unit)
119
{
120
    switch(unit) {
121
    case UNIT_RX: return _clock->get_rx_dboard_clock_rates();
122
    case UNIT_TX: return _clock->get_tx_dboard_clock_rates();
123
    default: UHD_THROW_INVALID_CODE_PATH();
124
    }
125
}
126

    
127
double usrp1_dboard_iface::get_clock_rate(unit_t unit)
128
{
129
    return _clock_rates[unit];
130
}
131

    
132
void usrp1_dboard_iface::set_clock_enabled(unit_t unit, bool enb)
133
{
134
    switch(unit) {
135
    case UNIT_RX: return _clock->enable_rx_dboard_clock(enb);
136
    case UNIT_TX: return _clock->enable_tx_dboard_clock(enb);
137
    }
138
}
139

    
140
/***********************************************************************
141
 * GPIO
142
 **********************************************************************/
143
void usrp1_dboard_iface::set_pin_ctrl(unit_t unit, boost::uint16_t value)
144
{
145
    switch(unit) {
146
    case UNIT_RX:
147
         _iface->poke32(FR_ATR_MASK_1, value);
148
         _iface->poke32(FR_ATR_MASK_3, 0x00000000);
149
         break; 
150
    case UNIT_TX:
151
         _iface->poke32(FR_ATR_MASK_0, value);
152
         _iface->poke32(FR_ATR_MASK_2, 0x00000000);
153
         break;
154
    }
155
}
156

    
157
void usrp1_dboard_iface::set_gpio_ddr(unit_t unit, boost::uint16_t value)
158
{
159
    switch(unit) {
160
    case UNIT_RX:
161
        _iface->poke32(FR_OE_1, 0xffff0000 | value);
162
        _iface->poke32(FR_OE_3, 0xffff0000);
163
        break; 
164
    case UNIT_TX:
165
        _iface->poke32(FR_OE_0, 0xffff0000 | value);
166
        _iface->poke32(FR_OE_2, 0xffff0000);
167
        break;
168
    }
169
}
170

    
171
void usrp1_dboard_iface::write_gpio(unit_t unit, boost::uint16_t value)
172
{
173
    switch(unit) {
174
    case UNIT_RX:
175
        _iface->poke32(FR_IO_1, 0xffff0000 | value);
176
        break;
177
    case UNIT_TX:
178
        _iface->poke32(FR_IO_0, 0xffff0000 | value);
179
        break;
180
    }
181
}
182

    
183
boost::uint16_t usrp1_dboard_iface::read_gpio(unit_t unit)
184
{
185
    boost::uint32_t out_value;
186
    boost::uint16_t ret_value;
187

    
188
    switch(unit) {
189
    case UNIT_RX:
190
        //magic
191
        out_value = _iface->peek32(1);
192
        ret_value = (out_value >> 16) & 0x0000ffff;
193
        return ret_value;
194
    case UNIT_TX:
195
        //magic
196
        out_value = _iface->peek32(1);
197
        ret_value = (out_value >>  0) & 0x0000ffff;
198
        return ret_value;
199
    }
200
    UHD_ASSERT_THROW(false);
201
}
202

    
203
void usrp1_dboard_iface::set_atr_reg(unit_t unit,
204
                                     atr_reg_t atr, boost::uint16_t value)
205
{
206
    if ((atr == ATR_REG_IDLE) || (atr == ATR_REG_FULL_DUPLEX)) {
207
        std::cerr << "error: set_atr_reg(): unsupported state" << std::endl;
208
        return;
209
    }
210

    
211
    switch(unit) {
212
    case UNIT_RX:
213
        _iface->poke32(FR_ATR_RXVAL_1, value);
214
        _iface->poke32(FR_ATR_RXVAL_3, 0x0000);
215
        break; 
216
    case UNIT_TX:
217
        //_iface->poke32(FR_ATR_TXVAL_0, value);
218
        _iface->poke32(FR_ATR_TXVAL_0, 0x0000);
219
        _iface->poke32(FR_ATR_TXVAL_2, 0x0000);
220
        break;
221
    }
222
}
223
/***********************************************************************
224
 * SPI
225
 **********************************************************************/
226
/*!
227
 * Static function to convert a unit type to a spi slave device number.
228
 * \param unit the dboard interface unit type enum
229
 * \return the slave device number
230
 */
231
static boost::uint32_t unit_to_otw_spi_dev(dboard_iface::unit_t unit)
232
{
233
    switch(unit) {
234
    case dboard_iface::UNIT_TX: return SPI_ENABLE_TX_A; 
235
    case dboard_iface::UNIT_RX: return SPI_ENABLE_RX_A;
236
    }
237
    throw std::invalid_argument("unknown unit type");
238

    
239
}
240

    
241
void usrp1_dboard_iface::write_spi(unit_t unit,
242
                                   const spi_config_t &config,
243
                                   boost::uint32_t data,
244
                                   size_t num_bits)
245
{
246
    _iface->transact_spi(unit_to_otw_spi_dev(unit),
247
                         config, data, num_bits, false);
248
}
249

    
250
boost::uint32_t usrp1_dboard_iface::read_write_spi(unit_t unit,
251
                                                   const spi_config_t &config,
252
                                                   boost::uint32_t data,
253
                                                   size_t num_bits)
254
{
255
    return _iface->transact_spi(unit_to_otw_spi_dev(unit),
256
                                config, data, num_bits, true);
257
}
258

    
259
/***********************************************************************
260
 * I2C
261
 **********************************************************************/
262
void usrp1_dboard_iface::write_i2c(boost::uint8_t addr,
263
                                   const byte_vector_t &bytes)
264
{
265
    return _iface->write_i2c(addr, bytes);
266
}
267

    
268
byte_vector_t usrp1_dboard_iface::read_i2c(boost::uint8_t addr,
269
                                           size_t num_bytes)
270
{
271
    return _iface->read_i2c(addr, num_bytes);
272
}
273

    
274
/***********************************************************************
275
 * Aux DAX/ADC
276
 **********************************************************************/
277
void usrp1_dboard_iface::write_aux_dac(dboard_iface::unit_t,
278
                                       aux_dac_t which, float value)
279
{
280
    //same aux dacs for each unit
281
    static const uhd::dict<aux_dac_t, usrp1_codec_ctrl::aux_dac_t>
282
        which_to_aux_dac = map_list_of
283
                                     (AUX_DAC_A, usrp1_codec_ctrl::AUX_DAC_A)
284
                                     (AUX_DAC_B, usrp1_codec_ctrl::AUX_DAC_B)
285
                                     (AUX_DAC_C, usrp1_codec_ctrl::AUX_DAC_C)
286
                                     (AUX_DAC_D, usrp1_codec_ctrl::AUX_DAC_D);
287

    
288
    _codec->write_aux_dac(which_to_aux_dac[which], value);
289
}
290

    
291
float usrp1_dboard_iface::read_aux_adc(dboard_iface::unit_t unit,
292
                                       aux_adc_t which)
293
{
294
    static const
295
    uhd::dict<unit_t, uhd::dict<aux_adc_t, usrp1_codec_ctrl::aux_adc_t> >
296
        unit_to_which_to_aux_adc = map_list_of(UNIT_RX, map_list_of
297
                                    (AUX_ADC_A, usrp1_codec_ctrl::AUX_ADC_A1)
298
                                    (AUX_ADC_B, usrp1_codec_ctrl::AUX_ADC_B1))
299
                                              (UNIT_TX, map_list_of
300
                                    (AUX_ADC_A, usrp1_codec_ctrl::AUX_ADC_A2)
301
                                    (AUX_ADC_B, usrp1_codec_ctrl::AUX_ADC_B2));
302

    
303
    return _codec->read_aux_adc(unit_to_which_to_aux_adc[unit][which]);
304
}