1ab1327c3SLei YU #pragma once 2ab1327c3SLei YU 3ab1327c3SLei YU #include "i2c_interface.hpp" 4ab1327c3SLei YU 5ab1327c3SLei YU namespace i2c 6ab1327c3SLei YU { 7ab1327c3SLei YU 8ab1327c3SLei YU class I2CDevice : public I2CInterface 9ab1327c3SLei YU { 10ab1327c3SLei YU private: 11ab1327c3SLei YU I2CDevice() = delete; 12ab1327c3SLei YU 139af82a5cSLei YU /** @brief Constructor 149af82a5cSLei YU * 159af82a5cSLei YU * Construct I2CDevice object from the bus id and device address 169af82a5cSLei YU * 17*d45a9a6dSShawn McCarney * Automatically opens the I2CDevice if initialState is OPEN. 18*d45a9a6dSShawn McCarney * 199af82a5cSLei YU * @param[in] busId - The i2c bus ID 209af82a5cSLei YU * @param[in] devAddr - The device address of the I2C device 21*d45a9a6dSShawn McCarney * @param[in] initialState - Initial state of the I2CDevice object 229af82a5cSLei YU */ 23*d45a9a6dSShawn McCarney explicit I2CDevice(uint8_t busId, uint8_t devAddr, 24*d45a9a6dSShawn McCarney InitialState initialState = InitialState::OPEN) : 25*d45a9a6dSShawn McCarney busId(busId), 26*d45a9a6dSShawn McCarney devAddr(devAddr), fd(INVALID_FD) 27ab1327c3SLei YU { 289af82a5cSLei YU busStr = "/dev/i2c-" + std::to_string(busId); 29*d45a9a6dSShawn McCarney if (initialState == InitialState::OPEN) 30*d45a9a6dSShawn McCarney { 319af82a5cSLei YU open(); 32ab1327c3SLei YU } 33*d45a9a6dSShawn McCarney } 34ab1327c3SLei YU 35*d45a9a6dSShawn McCarney /** @brief Invalid file descriptor */ 36*d45a9a6dSShawn McCarney static constexpr int INVALID_FD = -1; 379af82a5cSLei YU 389af82a5cSLei YU /** @brief The I2C bus ID */ 399af82a5cSLei YU uint8_t busId; 409af82a5cSLei YU 419af82a5cSLei YU /** @brief The i2c device address in the bus */ 429af82a5cSLei YU uint8_t devAddr; 439af82a5cSLei YU 449af82a5cSLei YU /** @brief The file descriptor of the opened i2c device */ 459af82a5cSLei YU int fd; 469af82a5cSLei YU 479af82a5cSLei YU /** @brief The i2c bus path in /dev */ 489af82a5cSLei YU std::string busStr; 499af82a5cSLei YU 50*d45a9a6dSShawn McCarney /** @brief Check that device interface is open 51*d45a9a6dSShawn McCarney * 52*d45a9a6dSShawn McCarney * @throw I2CException if device is not open 53*d45a9a6dSShawn McCarney */ 54*d45a9a6dSShawn McCarney void checkIsOpen() const 55*d45a9a6dSShawn McCarney { 56*d45a9a6dSShawn McCarney if (!isOpen()) 57*d45a9a6dSShawn McCarney { 58*d45a9a6dSShawn McCarney throw I2CException("Device not open", busStr, devAddr); 59*d45a9a6dSShawn McCarney } 60*d45a9a6dSShawn McCarney } 61*d45a9a6dSShawn McCarney 62*d45a9a6dSShawn McCarney /** @brief Close device without throwing an exception if an error occurs */ 63*d45a9a6dSShawn McCarney void closeWithoutException() noexcept 64*d45a9a6dSShawn McCarney { 65*d45a9a6dSShawn McCarney try 66*d45a9a6dSShawn McCarney { 67*d45a9a6dSShawn McCarney close(); 68*d45a9a6dSShawn McCarney } 69*d45a9a6dSShawn McCarney catch (...) 70*d45a9a6dSShawn McCarney { 71*d45a9a6dSShawn McCarney } 72*d45a9a6dSShawn McCarney } 73*d45a9a6dSShawn McCarney 7492e89eb5SLei YU /** @brief Check i2c adapter read functionality 7592e89eb5SLei YU * 7692e89eb5SLei YU * Check if the i2c adapter has the functionality specified by the SMBus 7792e89eb5SLei YU * transaction type 7892e89eb5SLei YU * 7992e89eb5SLei YU * @param[in] type - The SMBus transaction type defined in linux/i2c.h 8092e89eb5SLei YU * 8192e89eb5SLei YU * @throw I2CException if the function is not supported 8292e89eb5SLei YU */ 8392e89eb5SLei YU void checkReadFuncs(int type); 8492e89eb5SLei YU 8534fb8bdaSLei YU /** @brief Check i2c adapter write functionality 8634fb8bdaSLei YU * 8734fb8bdaSLei YU * Check if the i2c adapter has the functionality specified by the SMBus 8834fb8bdaSLei YU * transaction type 8934fb8bdaSLei YU * 9034fb8bdaSLei YU * @param[in] type - The SMBus transaction type defined in linux/i2c.h 9134fb8bdaSLei YU * 9234fb8bdaSLei YU * @throw I2CException if the function is not supported 9334fb8bdaSLei YU */ 9434fb8bdaSLei YU void checkWriteFuncs(int type); 9534fb8bdaSLei YU 96ab1327c3SLei YU public: 97*d45a9a6dSShawn McCarney /** @copydoc I2CInterface::~I2CInterface() */ 989af82a5cSLei YU ~I2CDevice() 999af82a5cSLei YU { 100*d45a9a6dSShawn McCarney if (isOpen()) 101*d45a9a6dSShawn McCarney { 102*d45a9a6dSShawn McCarney // Note: destructors must not throw exceptions 103*d45a9a6dSShawn McCarney closeWithoutException(); 1049af82a5cSLei YU } 105*d45a9a6dSShawn McCarney } 106*d45a9a6dSShawn McCarney 107*d45a9a6dSShawn McCarney /** @copydoc I2CInterface::open() */ 108*d45a9a6dSShawn McCarney void open(); 109*d45a9a6dSShawn McCarney 110*d45a9a6dSShawn McCarney /** @copydoc I2CInterface::isOpen() */ 111*d45a9a6dSShawn McCarney bool isOpen() const 112*d45a9a6dSShawn McCarney { 113*d45a9a6dSShawn McCarney return (fd != INVALID_FD); 114*d45a9a6dSShawn McCarney } 115*d45a9a6dSShawn McCarney 116*d45a9a6dSShawn McCarney /** @copydoc I2CInterface::close() */ 117*d45a9a6dSShawn McCarney void close(); 118ab1327c3SLei YU 119ab1327c3SLei YU /** @copydoc I2CInterface::read(uint8_t&) */ 120ab1327c3SLei YU void read(uint8_t& data) override; 121ab1327c3SLei YU 122ab1327c3SLei YU /** @copydoc I2CInterface::read(uint8_t,uint8_t&) */ 123ab1327c3SLei YU void read(uint8_t addr, uint8_t& data) override; 124ab1327c3SLei YU 125ab1327c3SLei YU /** @copydoc I2CInterface::read(uint8_t,uint16_t&) */ 126ab1327c3SLei YU void read(uint8_t addr, uint16_t& data) override; 127ab1327c3SLei YU 1281d103428SLei YU /** @copydoc I2CInterface::read(uint8_t,uint8_t&,uint8_t*,Mode) */ 1291d103428SLei YU void read(uint8_t addr, uint8_t& size, uint8_t* data, 1301d103428SLei YU Mode mode = Mode::SMBUS) override; 131ab1327c3SLei YU 132ab1327c3SLei YU /** @copydoc I2CInterface::write(uint8_t) */ 133ab1327c3SLei YU void write(uint8_t data) override; 134ab1327c3SLei YU 135ab1327c3SLei YU /** @copydoc I2CInterface::write(uint8_t,uint8_t) */ 136ab1327c3SLei YU void write(uint8_t addr, uint8_t data) override; 137ab1327c3SLei YU 138ab1327c3SLei YU /** @copydoc I2CInterface::write(uint8_t,uint16_t) */ 139ab1327c3SLei YU void write(uint8_t addr, uint16_t data) override; 140ab1327c3SLei YU 1411d103428SLei YU /** @copydoc I2CInterface::write(uint8_t,uint8_t,const uint8_t*,Mode) */ 1421d103428SLei YU void write(uint8_t addr, uint8_t size, const uint8_t* data, 1431d103428SLei YU Mode mode = Mode::SMBUS) override; 144ab1327c3SLei YU 145ab1327c3SLei YU /** @brief Create an I2CInterface instance 146ab1327c3SLei YU * 147*d45a9a6dSShawn McCarney * Automatically opens the I2CInterface if initialState is OPEN. 148*d45a9a6dSShawn McCarney * 149ab1327c3SLei YU * @param[in] busId - The i2c bus ID 150ab1327c3SLei YU * @param[in] devAddr - The device address of the i2c 151*d45a9a6dSShawn McCarney * @param[in] initialState - Initial state of the I2CInterface object 152ab1327c3SLei YU * 153ab1327c3SLei YU * @return The unique_ptr holding the I2CInterface 154ab1327c3SLei YU */ 155*d45a9a6dSShawn McCarney static std::unique_ptr<I2CInterface> 156*d45a9a6dSShawn McCarney create(uint8_t busId, uint8_t devAddr, 157*d45a9a6dSShawn McCarney InitialState initialState = InitialState::OPEN); 158ab1327c3SLei YU }; 159ab1327c3SLei YU 160ab1327c3SLei YU } // namespace i2c 161