blob: b5ddcb850029f552d9d81eaed4b92ab32daf5ec2 [file] [log] [blame]
Lei YUab1327c2019-11-04 16:53:39 +08001#pragma once
2
3#include "i2c_interface.hpp"
4
5namespace i2c
6{
7
8class I2CDevice : public I2CInterface
9{
10 private:
11 I2CDevice() = delete;
12
Lei YU9af82a52019-11-06 14:51:22 +080013 /** @brief Constructor
14 *
15 * Construct I2CDevice object from the bus id and device address
16 *
Shawn McCarneyd45a9a62019-12-10 18:35:44 -060017 * Automatically opens the I2CDevice if initialState is OPEN.
18 *
Lei YU9af82a52019-11-06 14:51:22 +080019 * @param[in] busId - The i2c bus ID
20 * @param[in] devAddr - The device address of the I2C device
Shawn McCarneyd45a9a62019-12-10 18:35:44 -060021 * @param[in] initialState - Initial state of the I2CDevice object
Lei YU9af82a52019-11-06 14:51:22 +080022 */
Shawn McCarneyd45a9a62019-12-10 18:35:44 -060023 explicit I2CDevice(uint8_t busId, uint8_t devAddr,
24 InitialState initialState = InitialState::OPEN) :
25 busId(busId),
26 devAddr(devAddr), fd(INVALID_FD)
Lei YUab1327c2019-11-04 16:53:39 +080027 {
Lei YU9af82a52019-11-06 14:51:22 +080028 busStr = "/dev/i2c-" + std::to_string(busId);
Shawn McCarneyd45a9a62019-12-10 18:35:44 -060029 if (initialState == InitialState::OPEN)
30 {
31 open();
32 }
Lei YUab1327c2019-11-04 16:53:39 +080033 }
34
Shawn McCarneyd45a9a62019-12-10 18:35:44 -060035 /** @brief Invalid file descriptor */
36 static constexpr int INVALID_FD = -1;
Lei YU9af82a52019-11-06 14:51:22 +080037
38 /** @brief The I2C bus ID */
39 uint8_t busId;
40
41 /** @brief The i2c device address in the bus */
42 uint8_t devAddr;
43
44 /** @brief The file descriptor of the opened i2c device */
45 int fd;
46
47 /** @brief The i2c bus path in /dev */
48 std::string busStr;
49
Shawn McCarneyd45a9a62019-12-10 18:35:44 -060050 /** @brief Check that device interface is open
51 *
52 * @throw I2CException if device is not open
53 */
54 void checkIsOpen() const
55 {
56 if (!isOpen())
57 {
58 throw I2CException("Device not open", busStr, devAddr);
59 }
60 }
61
62 /** @brief Close device without throwing an exception if an error occurs */
63 void closeWithoutException() noexcept
64 {
65 try
66 {
67 close();
68 }
69 catch (...)
70 {
71 }
72 }
73
Lei YU92e89eb2019-11-06 18:08:25 +080074 /** @brief Check i2c adapter read functionality
75 *
76 * Check if the i2c adapter has the functionality specified by the SMBus
77 * transaction type
78 *
79 * @param[in] type - The SMBus transaction type defined in linux/i2c.h
80 *
81 * @throw I2CException if the function is not supported
82 */
83 void checkReadFuncs(int type);
84
Lei YU34fb8bd2019-11-07 14:24:20 +080085 /** @brief Check i2c adapter write functionality
86 *
87 * Check if the i2c adapter has the functionality specified by the SMBus
88 * transaction type
89 *
90 * @param[in] type - The SMBus transaction type defined in linux/i2c.h
91 *
92 * @throw I2CException if the function is not supported
93 */
94 void checkWriteFuncs(int type);
95
Lei YUab1327c2019-11-04 16:53:39 +080096 public:
Shawn McCarneyd45a9a62019-12-10 18:35:44 -060097 /** @copydoc I2CInterface::~I2CInterface() */
Lei YU9af82a52019-11-06 14:51:22 +080098 ~I2CDevice()
99 {
Shawn McCarneyd45a9a62019-12-10 18:35:44 -0600100 if (isOpen())
101 {
102 // Note: destructors must not throw exceptions
103 closeWithoutException();
104 }
Lei YU9af82a52019-11-06 14:51:22 +0800105 }
Lei YUab1327c2019-11-04 16:53:39 +0800106
Shawn McCarneyd45a9a62019-12-10 18:35:44 -0600107 /** @copydoc I2CInterface::open() */
108 void open();
109
110 /** @copydoc I2CInterface::isOpen() */
111 bool isOpen() const
112 {
113 return (fd != INVALID_FD);
114 }
115
116 /** @copydoc I2CInterface::close() */
117 void close();
118
Lei YUab1327c2019-11-04 16:53:39 +0800119 /** @copydoc I2CInterface::read(uint8_t&) */
120 void read(uint8_t& data) override;
121
122 /** @copydoc I2CInterface::read(uint8_t,uint8_t&) */
123 void read(uint8_t addr, uint8_t& data) override;
124
125 /** @copydoc I2CInterface::read(uint8_t,uint16_t&) */
126 void read(uint8_t addr, uint16_t& data) override;
127
Lei YU1d103422019-11-29 14:00:02 +0800128 /** @copydoc I2CInterface::read(uint8_t,uint8_t&,uint8_t*,Mode) */
129 void read(uint8_t addr, uint8_t& size, uint8_t* data,
130 Mode mode = Mode::SMBUS) override;
Lei YUab1327c2019-11-04 16:53:39 +0800131
132 /** @copydoc I2CInterface::write(uint8_t) */
133 void write(uint8_t data) override;
134
135 /** @copydoc I2CInterface::write(uint8_t,uint8_t) */
136 void write(uint8_t addr, uint8_t data) override;
137
138 /** @copydoc I2CInterface::write(uint8_t,uint16_t) */
139 void write(uint8_t addr, uint16_t data) override;
140
Lei YU1d103422019-11-29 14:00:02 +0800141 /** @copydoc I2CInterface::write(uint8_t,uint8_t,const uint8_t*,Mode) */
142 void write(uint8_t addr, uint8_t size, const uint8_t* data,
143 Mode mode = Mode::SMBUS) override;
Lei YUab1327c2019-11-04 16:53:39 +0800144
145 /** @brief Create an I2CInterface instance
146 *
Shawn McCarneyd45a9a62019-12-10 18:35:44 -0600147 * Automatically opens the I2CInterface if initialState is OPEN.
148 *
Lei YUab1327c2019-11-04 16:53:39 +0800149 * @param[in] busId - The i2c bus ID
150 * @param[in] devAddr - The device address of the i2c
Shawn McCarneyd45a9a62019-12-10 18:35:44 -0600151 * @param[in] initialState - Initial state of the I2CInterface object
Lei YUab1327c2019-11-04 16:53:39 +0800152 *
153 * @return The unique_ptr holding the I2CInterface
154 */
Shawn McCarneyd45a9a62019-12-10 18:35:44 -0600155 static std::unique_ptr<I2CInterface>
156 create(uint8_t busId, uint8_t devAddr,
157 InitialState initialState = InitialState::OPEN);
Lei YUab1327c2019-11-04 16:53:39 +0800158};
159
160} // namespace i2c