aboutsummaryrefslogtreecommitdiffstats
path: root/host/include/uhd/types/serial.hpp
blob: b68c68870fc511a025ecf92560b9b7015fe6081c (plain) (blame)
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
//
// Copyright 2010-2013 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//

#ifndef INCLUDED_UHD_TYPES_SERIAL_HPP
#define INCLUDED_UHD_TYPES_SERIAL_HPP

#include <uhd/config.hpp>
#include <stdint.h>
#include <boost/shared_ptr.hpp>
#include <vector>

namespace uhd {

/*!
 * Byte vector typedef for passing data in and out of I2C interfaces.
 */
typedef std::vector<uint8_t> byte_vector_t;

/*!
 * The i2c interface class:
 * Provides i2c and eeprom functionality.
 * A subclass should only have to implement the i2c routines.
 * An eeprom implementation comes for free with the interface.
 *
 * The eeprom routines are implemented on top of i2c.
 * The built in eeprom implementation only does single
 * byte reads and byte writes over the i2c interface,
 * so it should be portable across multiple eeproms.
 * Override the eeprom routines if this is not acceptable.
 */
class UHD_API i2c_iface
{
public:
    typedef boost::shared_ptr<i2c_iface> sptr;

    virtual ~i2c_iface(void);

    //! Create an i2c_iface than can talk to 16 bit addressable EEPROMS
    i2c_iface::sptr eeprom16(void);

    /*!
     * Write bytes over the i2c.
     * \param addr the address
     * \param buf the vector of bytes
     */
    virtual void write_i2c(uint16_t addr, const byte_vector_t& buf) = 0;

    /*!
     * Read bytes over the i2c.
     * \param addr the address
     * \param num_bytes number of bytes to read
     * \return a vector of bytes
     */
    virtual byte_vector_t read_i2c(uint16_t addr, size_t num_bytes) = 0;

    /*!
     * Write bytes to an eeprom.
     * \param addr the address
     * \param offset byte offset
     * \param buf the vector of bytes
     */
    virtual void write_eeprom(uint16_t addr, uint16_t offset, const byte_vector_t& buf);

    /*!
     * Read bytes from an eeprom.
     * \param addr the address
     * \param offset byte offset
     * \param num_bytes number of bytes to read
     * \return a vector of bytes
     */
    virtual byte_vector_t read_eeprom(uint16_t addr, uint16_t offset, size_t num_bytes);
};

/*!
 * The SPI configuration struct:
 * Used to configure a SPI transaction interface.
 */
struct UHD_API spi_config_t
{
    /*!
     * The edge type specifies when data is valid
     * relative to the edge of the serial clock.
     */
    enum edge_t { EDGE_RISE = 'r', EDGE_FALL = 'f' };

    //! on what edge is the mosi data valid?
    edge_t mosi_edge;

    //! on what edge is the miso data valid?
    edge_t miso_edge;

    //! Set the clock speed for this transaction
    bool use_custom_divider;

    //! Optionally set the SPI clock divider for this transaction
    size_t divider;

    /*!
     * Create a new spi config.
     * \param edge the default edge for mosi and miso
     */
    spi_config_t(edge_t edge = EDGE_RISE);
};

/*!
 * The SPI interface class.
 * Provides routines to transact SPI and do other useful things which haven't been defined
 * yet.
 */
class UHD_API spi_iface
{
public:
    typedef boost::shared_ptr<spi_iface> sptr;

    virtual ~spi_iface(void);

    /*!
     * Perform a spi transaction.
     * \param which_slave the slave device number
     * \param config spi config args
     * \param data the bits to write
     * \param num_bits how many bits in data
     * \param readback true to readback a value
     * \return spi data if readback set
     */
    virtual uint32_t transact_spi(int which_slave,
        const spi_config_t& config,
        uint32_t data,
        size_t num_bits,
        bool readback) = 0;

    /*!
     * Read from the SPI bus.
     * \param which_slave the slave device number
     * \param config spi config args
     * \param data the bits to write out (be sure to set write bit)
     * \param num_bits how many bits in data
     * \return spi data
     */
    virtual uint32_t read_spi(
        int which_slave, const spi_config_t& config, uint32_t data, size_t num_bits);

    /*!
     * Write to the SPI bus.
     * \param which_slave the slave device number
     * \param config spi config args
     * \param data the bits to write
     * \param num_bits how many bits in data
     */
    virtual void write_spi(
        int which_slave, const spi_config_t& config, uint32_t data, size_t num_bits);
};

/*!
 * UART interface to write and read strings.
 */
class UHD_API uart_iface
{
public:
    typedef boost::shared_ptr<uart_iface> sptr;

    virtual ~uart_iface(void);

    /*!
     * Write to a serial port.
     * \param buf the data to write
     */
    virtual void write_uart(const std::string& buf) = 0;

    /*!
     * Read a line from a serial port.
     * \param timeout the timeout in seconds
     * \return the line or empty string upon timeout
     */
    virtual std::string read_uart(double timeout) = 0;
};

} // namespace uhd

#endif /* INCLUDED_UHD_TYPES_SERIAL_HPP */