blob: 152f1e9fa42cc9265c7e9896c71132f045f4ecec [file] [log] [blame]
Lei YUab1327c2019-11-04 16:53:39 +08001#pragma once
2
3#include <cstdint>
4#include <cstring>
5#include <exception>
6#include <iostream>
7#include <memory>
8#include <sstream>
9#include <string>
10#include <vector>
11
12namespace i2c
13{
14
15class I2CException : public std::exception
16{
17 public:
18 explicit I2CException(const std::string& info, const std::string& bus,
19 uint8_t addr, int errorCode = 0) :
20 bus(bus),
21 addr(addr), errorCode(errorCode)
22 {
23 std::stringstream ss;
24 ss << "I2CException: " << info << ": bus " << bus << ", addr 0x"
25 << std::hex << static_cast<int>(addr);
26 if (errorCode != 0)
27 {
28 ss << std::dec << ", errno " << errorCode << ": "
29 << strerror(errorCode);
30 }
31 errStr = ss.str();
32 }
33 virtual ~I2CException() = default;
34
35 const char* what() const noexcept override
36 {
37 return errStr.c_str();
38 }
39 std::string bus;
40 uint8_t addr;
41 int errorCode;
42 std::string errStr;
43};
44
45class I2CInterface
46{
47 public:
48 virtual ~I2CInterface() = default;
49
Lei YU1d103422019-11-29 14:00:02 +080050 /** @brief The block transaction mode */
51 enum class Mode
52 {
53 SMBUS,
54 I2C,
55 };
56
Lei YUab1327c2019-11-04 16:53:39 +080057 /** @brief Read byte data from i2c
58 *
59 * @param[out] data - The data read from the i2c device
60 *
61 * @throw I2CException on error
62 */
63 virtual void read(uint8_t& data) = 0;
64
65 /** @brief Read byte data from i2c
66 *
67 * @param[in] addr - The register address of the i2c device
68 * @param[out] data - The data read from the i2c device
69 *
70 * @throw I2CException on error
71 */
72 virtual void read(uint8_t addr, uint8_t& data) = 0;
73
74 /** @brief Read word data from i2c
75 *
76 * @param[in] addr - The register address of the i2c device
77 * @param[out] data - The data read from the i2c device
78 *
79 * @throw I2CException on error
80 */
81 virtual void read(uint8_t addr, uint16_t& data) = 0;
82
83 /** @brief Read block data from i2c
84 *
85 * @param[in] addr - The register address of the i2c device
Lei YU1d103422019-11-29 14:00:02 +080086 * @param[in,out] size - The out parameter to indicate the size of data read
87 * from i2c device; when mode is I2C, it is also the
88 * input parameter to indicate how many bytes to read
Lei YUab1327c2019-11-04 16:53:39 +080089 * @param[out] data - The pointer to buffer to read from the i2c device,
90 * the buffer shall be big enough to hold the data
91 * returned by the device. SMBus allows at most 32
92 * bytes.
Lei YU1d103422019-11-29 14:00:02 +080093 * @param[in] mode - The block read mode, either SMBus or I2C.
94 * Internally, it invokes functions from libi2c:
95 * * For SMBus: i2c_smbus_read_block_data()
96 * * For I2C: i2c_smbus_read_i2c_block_data()
Lei YUab1327c2019-11-04 16:53:39 +080097 *
98 * @throw I2CException on error
99 */
Lei YU1d103422019-11-29 14:00:02 +0800100 virtual void read(uint8_t addr, uint8_t& size, uint8_t* data,
101 Mode mode = Mode::SMBUS) = 0;
Lei YUab1327c2019-11-04 16:53:39 +0800102
103 /** @brief Write byte data to i2c
104 *
105 * @param[in] data - The data to write to the i2c device
106 *
107 * @throw I2CException on error
108 */
109 virtual void write(uint8_t data) = 0;
110
111 /** @brief Write byte data to i2c
112 *
113 * @param[in] addr - The register address of the i2c device
114 * @param[in] data - The data to write to the i2c device
115 *
116 * @throw I2CException on error
117 */
118 virtual void write(uint8_t addr, uint8_t data) = 0;
119
120 /** @brief Write word data to i2c
121 *
122 * @param[in] addr - The register address of the i2c device
123 * @param[in] data - The data to write to the i2c device
124 *
125 * @throw I2CException on error
126 */
127 virtual void write(uint8_t addr, uint16_t data) = 0;
128
129 /** @brief Write block data to i2c
130 *
131 * @param[in] addr - The register address of the i2c device
132 * @param[in] size - The size of data to write, SMBus allows at most 32
133 * bytes
134 * @param[in] data - The data to write to the i2c device
Lei YU1d103422019-11-29 14:00:02 +0800135 * @param[in] mode - The block write mode, either SMBus or I2C.
136 * Internally, it invokes functions from libi2c:
137 * * For SMBus: i2c_smbus_write_block_data()
138 * * For I2C: i2c_smbus_write_i2c_block_data()
Lei YUab1327c2019-11-04 16:53:39 +0800139 *
140 * @throw I2CException on error
141 */
Lei YU1d103422019-11-29 14:00:02 +0800142 virtual void write(uint8_t addr, uint8_t size, const uint8_t* data,
143 Mode mode = Mode::SMBUS) = 0;
Lei YUab1327c2019-11-04 16:53:39 +0800144};
145
146/** @brief Create an I2CInterface instance
147 *
148 * @param[in] busId - The i2c bus ID
149 * @param[in] devAddr - The device address of the i2c
150 *
151 * @return The unique_ptr holding the I2CInterface
152 */
153std::unique_ptr<I2CInterface> create(uint8_t busId, uint8_t devAddr);
154
155} // namespace i2c