1 //
2 // Copyright 2010-2013 Ettus Research LLC
3 // Copyright 2018 Ettus Research, a National Instruments Company
4 //
5 // SPDX-License-Identifier: GPL-3.0-or-later
6 //
7 
8 #pragma once
9 
10 #include <uhd/config.hpp>
11 #include <stdint.h>
12 #include <memory>
13 #include <string>
14 #include <vector>
15 
16 namespace uhd {
17 
18 /*!
19  * Byte vector typedef for passing data in and out of I2C interfaces.
20  */
21 typedef std::vector<uint8_t> byte_vector_t;
22 
23 /*!
24  * The i2c interface class:
25  * Provides i2c and eeprom functionality.
26  * A subclass should only have to implement the i2c routines.
27  * An eeprom implementation comes for free with the interface.
28  *
29  * The eeprom routines are implemented on top of i2c.
30  * The built in eeprom implementation only does single
31  * byte reads and byte writes over the i2c interface,
32  * so it should be portable across multiple eeproms.
33  * Override the eeprom routines if this is not acceptable.
34  */
35 class UHD_API i2c_iface
36 {
37 public:
38     typedef std::shared_ptr<i2c_iface> sptr;
39 
40     virtual ~i2c_iface(void);
41 
42     //! Create an i2c_iface than can talk to 16 bit addressable EEPROMS
43     i2c_iface::sptr eeprom16(void);
44 
45     /*!
46      * Write bytes over the i2c.
47      * \param addr the address
48      * \param buf the vector of bytes
49      */
50     virtual void write_i2c(uint16_t addr, const byte_vector_t& buf) = 0;
51 
52     /*!
53      * Read bytes over the i2c.
54      * \param addr the address
55      * \param num_bytes number of bytes to read
56      * \return a vector of bytes
57      */
58     virtual byte_vector_t read_i2c(uint16_t addr, size_t num_bytes) = 0;
59 
60     /*!
61      * Write bytes to an eeprom.
62      * \param addr the address
63      * \param offset byte offset
64      * \param buf the vector of bytes
65      */
66     virtual void write_eeprom(uint16_t addr, uint16_t offset, const byte_vector_t& buf);
67 
68     /*!
69      * Read bytes from an eeprom.
70      * \param addr the address
71      * \param offset byte offset
72      * \param num_bytes number of bytes to read
73      * \return a vector of bytes
74      */
75     virtual byte_vector_t read_eeprom(uint16_t addr, uint16_t offset, size_t num_bytes);
76 };
77 
78 /*!
79  * The SPI configuration struct:
80  * Used to configure a SPI transaction interface.
81  */
82 struct UHD_API spi_config_t
83 {
84     /*!
85      * The edge type specifies when data is valid
86      * relative to the edge of the serial clock.
87      */
88     enum edge_t { EDGE_RISE = 'r', EDGE_FALL = 'f' };
89 
90     //! on what edge is the mosi data valid?
91     edge_t mosi_edge;
92 
93     //! on what edge is the miso data valid?
94     edge_t miso_edge;
95 
96     //! Set the clock speed for this transaction
97     bool use_custom_divider;
98 
99     //! Optionally set the SPI clock divider for this transaction
100     size_t divider;
101 
102     /*!
103      * Create a new spi config.
104      * \param edge the default edge for mosi and miso
105      */
106     spi_config_t(edge_t edge = EDGE_RISE);
107 };
108 
109 /*!
110  * The SPI interface class.
111  * Provides routines to transact SPI and do other useful things which haven't been defined
112  * yet.
113  */
114 class UHD_API spi_iface
115 {
116 public:
117     typedef std::shared_ptr<spi_iface> sptr;
118 
119     virtual ~spi_iface(void);
120 
121     /*!
122      * Perform a spi transaction.
123      * \param which_slave the slave device number
124      * \param config spi config args
125      * \param data the bits to write
126      * \param num_bits how many bits in data
127      * \param readback true to readback a value
128      * \return spi data if readback set
129      */
130     virtual uint32_t transact_spi(int which_slave,
131         const spi_config_t& config,
132         uint32_t data,
133         size_t num_bits,
134         bool readback) = 0;
135 
136     /*!
137      * Read from the SPI bus.
138      * \param which_slave the slave device number
139      * \param config spi config args
140      * \param data the bits to write out (be sure to set write bit)
141      * \param num_bits how many bits in data
142      * \return spi data
143      */
144     virtual uint32_t read_spi(
145         int which_slave, const spi_config_t& config, uint32_t data, size_t num_bits);
146 
147     /*!
148      * Write to the SPI bus.
149      * \param which_slave the slave device number
150      * \param config spi config args
151      * \param data the bits to write
152      * \param num_bits how many bits in data
153      */
154     virtual void write_spi(
155         int which_slave, const spi_config_t& config, uint32_t data, size_t num_bits);
156 };
157 
158 /*!
159  * UART interface to write and read strings.
160  */
161 class UHD_API uart_iface
162 {
163 public:
164     typedef std::shared_ptr<uart_iface> sptr;
165 
166     virtual ~uart_iface(void);
167 
168     /*!
169      * Write to a serial port.
170      * \param buf the data to write
171      */
172     virtual void write_uart(const std::string& buf) = 0;
173 
174     /*!
175      * Read a line from a serial port.
176      * \param timeout the timeout in seconds
177      * \return the line or empty string upon timeout
178      */
179     virtual std::string read_uart(double timeout) = 0;
180 };
181 
182 } // namespace uhd
183