aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/usrp1e/dboard_interface.cpp
blob: ef91014ac1d77c045f16ecc076bb2625949fe0ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
//
// Copyright 2010 Ettus Research LLC
//
// 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
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program 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, see <http://www.gnu.org/licenses/>.
//

#include <uhd/utils.hpp>
#include <algorithm> //std::copy
#include "usrp1e_impl.hpp"
#include <linux/usrp1_e.h>

using namespace uhd::usrp;

class usrp1e_dboard_interface : public dboard_interface{
public:
    usrp1e_dboard_interface(usrp1e_impl *impl);
    ~usrp1e_dboard_interface(void);

    void write_aux_dac(unit_type_t, int, int);
    int read_aux_adc(unit_type_t, int);

    void set_atr_reg(gpio_bank_t, boost::uint16_t, boost::uint16_t, boost::uint16_t);
    void set_gpio_ddr(gpio_bank_t, boost::uint16_t, boost::uint16_t);
    void write_gpio(gpio_bank_t, boost::uint16_t, boost::uint16_t);
    boost::uint16_t read_gpio(gpio_bank_t);

    void write_i2c(int, const byte_vector_t &);
    byte_vector_t read_i2c(int, size_t);

    double get_rx_clock_rate(void);
    double get_tx_clock_rate(void);

private:
    byte_vector_t transact_spi(
        spi_dev_t dev,
        spi_latch_t latch,
        spi_push_t push,
        const byte_vector_t &buf,
        bool readback
    );

    usrp1e_impl *_impl;
};

/***********************************************************************
 * Make Function
 **********************************************************************/
dboard_interface::sptr make_usrp1e_dboard_interface(usrp1e_impl *impl){
    return dboard_interface::sptr(new usrp1e_dboard_interface(impl));
}

/***********************************************************************
 * Structors
 **********************************************************************/
usrp1e_dboard_interface::usrp1e_dboard_interface(usrp1e_impl *impl){
    _impl = impl;
}

usrp1e_dboard_interface::~usrp1e_dboard_interface(void){
    /* NOP */
}

/***********************************************************************
 * Clock Rates
 **********************************************************************/
double usrp1e_dboard_interface::get_rx_clock_rate(void){
    throw std::runtime_error("not implemented");
}

double usrp1e_dboard_interface::get_tx_clock_rate(void){
    throw std::runtime_error("not implemented");
}

/***********************************************************************
 * GPIO
 **********************************************************************/
void usrp1e_dboard_interface::set_gpio_ddr(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){
    throw std::runtime_error("not implemented");
}

void usrp1e_dboard_interface::write_gpio(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){
    throw std::runtime_error("not implemented");
}

boost::uint16_t usrp1e_dboard_interface::read_gpio(gpio_bank_t bank){
    throw std::runtime_error("not implemented");
}

void usrp1e_dboard_interface::set_atr_reg(gpio_bank_t bank, boost::uint16_t tx_value, boost::uint16_t rx_value, boost::uint16_t mask){
    throw std::runtime_error("not implemented");
}

/***********************************************************************
 * SPI
 **********************************************************************/
dboard_interface::byte_vector_t usrp1e_dboard_interface::transact_spi(
    spi_dev_t dev,
    spi_latch_t latch,
    spi_push_t push,
    const byte_vector_t &buf,
    bool readback
){
    //load data struct
    usrp_e_spi data;
    data.readback = (readback)? UE_SPI_TXRX : UE_SPI_TXONLY;
    data.slave = (dev == SPI_RX_DEV)? UE_SPI_CTRL_RXNEG : UE_SPI_CTRL_TXNEG;
    data.length = buf.size() * 8; //bytes to bits
    boost::uint8_t *data_bytes = reinterpret_cast<boost::uint8_t*>(&data.data);

    //load the data
    ASSERT_THROW(buf.size() <= sizeof(data.data));
    std::copy(buf.begin(), buf.end(), data_bytes);

    //load the flags
    data.flags = 0;
    data.flags |= (latch == SPI_LATCH_RISE)? UE_SPI_LATCH_RISE : UE_SPI_LATCH_FALL;
    data.flags |= (push ==  SPI_PUSH_RISE)?  UE_SPI_PUSH_RISE  : UE_SPI_PUSH_FALL;

    //call the spi ioctl
    _impl->ioctl(USRP_E_SPI, &data);

    //unload the data
    byte_vector_t ret(data.length/8); //bits to bytes
    ASSERT_THROW(ret.size() <= sizeof(data.data));
    std::copy(data_bytes, data_bytes+ret.size(), ret.begin());
    return ret;
}

/***********************************************************************
 * I2C
 **********************************************************************/
static const size_t max_i2c_data_bytes = 10;

void usrp1e_dboard_interface::write_i2c(int i2c_addr, const byte_vector_t &buf){
    //allocate some memory for this transaction
    ASSERT_THROW(buf.size() <= max_i2c_data_bytes);
    boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes];

    //load the data struct
    usrp_e_i2c &data = reinterpret_cast<usrp_e_i2c&>(mem);
    data.addr = i2c_addr;
    data.len = buf.size();
    std::copy(buf.begin(), buf.end(), data.data);

    //call the spi ioctl
    _impl->ioctl(USRP_E_I2C_WRITE, &data);
}

dboard_interface::byte_vector_t usrp1e_dboard_interface::read_i2c(int i2c_addr, size_t num_bytes){
    //allocate some memory for this transaction
    ASSERT_THROW(num_bytes <= max_i2c_data_bytes);
    boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes];

    //load the data struct
    usrp_e_i2c &data = reinterpret_cast<usrp_e_i2c&>(mem);
    data.addr = i2c_addr;
    data.len = num_bytes;

    //call the spi ioctl
    _impl->ioctl(USRP_E_I2C_READ, &data);

    //unload the data
    byte_vector_t ret(data.len);
    ASSERT_THROW(ret.size() == num_bytes);
    std::copy(data.data, data.data+ret.size(), ret.begin());
    return ret;
}

/***********************************************************************
 * Aux DAX/ADC
 **********************************************************************/
void usrp1e_dboard_interface::write_aux_dac(dboard_interface::unit_type_t unit, int which, int value){
    throw std::runtime_error("not implemented");
}

int usrp1e_dboard_interface::read_aux_adc(dboard_interface::unit_type_t unit, int which){
    throw std::runtime_error("not implemented");
}