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 * 17d45a9a6dSShawn McCarney * Automatically opens the I2CDevice if initialState is OPEN. 18d45a9a6dSShawn McCarney * 199af82a5cSLei YU * @param[in] busId - The i2c bus ID 209af82a5cSLei YU * @param[in] devAddr - The device address of the I2C device 21d45a9a6dSShawn McCarney * @param[in] initialState - Initial state of the I2CDevice object 22*770de580SShawn McCarney * @param[in] maxRetries - Maximum number of times to retry an I2C operation 239af82a5cSLei YU */ 24d45a9a6dSShawn McCarney explicit I2CDevice(uint8_t busId, uint8_t devAddr, 25*770de580SShawn McCarney InitialState initialState = InitialState::OPEN, 26*770de580SShawn McCarney int maxRetries = 0) : 27d45a9a6dSShawn McCarney busId(busId), 28*770de580SShawn McCarney devAddr(devAddr), maxRetries(maxRetries) 29ab1327c3SLei YU { 309af82a5cSLei YU busStr = "/dev/i2c-" + std::to_string(busId); 31d45a9a6dSShawn McCarney if (initialState == InitialState::OPEN) 32d45a9a6dSShawn McCarney { 339af82a5cSLei YU open(); 34ab1327c3SLei YU } 35d45a9a6dSShawn McCarney } 36ab1327c3SLei YU 37d45a9a6dSShawn McCarney /** @brief Invalid file descriptor */ 38d45a9a6dSShawn McCarney static constexpr int INVALID_FD = -1; 399af82a5cSLei YU 4038ed88d6SShawn McCarney /** @brief Empty adapter functionality value with no bit flags set */ 4138ed88d6SShawn McCarney static constexpr unsigned long NO_FUNCS = 0; 4238ed88d6SShawn McCarney 439af82a5cSLei YU /** @brief The I2C bus ID */ 449af82a5cSLei YU uint8_t busId; 459af82a5cSLei YU 469af82a5cSLei YU /** @brief The i2c device address in the bus */ 479af82a5cSLei YU uint8_t devAddr; 489af82a5cSLei YU 49*770de580SShawn McCarney /** @brief Maximum number of times to retry an I2C operation */ 50*770de580SShawn McCarney int maxRetries = 0; 51*770de580SShawn McCarney 529af82a5cSLei YU /** @brief The file descriptor of the opened i2c device */ 5338ed88d6SShawn McCarney int fd = INVALID_FD; 549af82a5cSLei YU 559af82a5cSLei YU /** @brief The i2c bus path in /dev */ 569af82a5cSLei YU std::string busStr; 579af82a5cSLei YU 5838ed88d6SShawn McCarney /** @brief Cached I2C adapter functionality value */ 5938ed88d6SShawn McCarney unsigned long cachedFuncs = NO_FUNCS; 6038ed88d6SShawn McCarney 61d45a9a6dSShawn McCarney /** @brief Check that device interface is open 62d45a9a6dSShawn McCarney * 63d45a9a6dSShawn McCarney * @throw I2CException if device is not open 64d45a9a6dSShawn McCarney */ 65d45a9a6dSShawn McCarney void checkIsOpen() const 66d45a9a6dSShawn McCarney { 67d45a9a6dSShawn McCarney if (!isOpen()) 68d45a9a6dSShawn McCarney { 69d45a9a6dSShawn McCarney throw I2CException("Device not open", busStr, devAddr); 70d45a9a6dSShawn McCarney } 71d45a9a6dSShawn McCarney } 72d45a9a6dSShawn McCarney 73d45a9a6dSShawn McCarney /** @brief Close device without throwing an exception if an error occurs */ 74d45a9a6dSShawn McCarney void closeWithoutException() noexcept 75d45a9a6dSShawn McCarney { 76d45a9a6dSShawn McCarney try 77d45a9a6dSShawn McCarney { 78d45a9a6dSShawn McCarney close(); 79d45a9a6dSShawn McCarney } 80d45a9a6dSShawn McCarney catch (...) 810c9a33d6SAdriana Kobylak {} 82d45a9a6dSShawn McCarney } 83d45a9a6dSShawn McCarney 8438ed88d6SShawn McCarney /** @brief Get I2C adapter functionality 8538ed88d6SShawn McCarney * 8638ed88d6SShawn McCarney * Caches the adapter functionality value since it shouldn't change after 8738ed88d6SShawn McCarney * opening the device. 8838ed88d6SShawn McCarney * 8938ed88d6SShawn McCarney * @throw I2CException on error 9038ed88d6SShawn McCarney * @return Adapter functionality value 9138ed88d6SShawn McCarney */ 9238ed88d6SShawn McCarney unsigned long getFuncs(); 9338ed88d6SShawn McCarney 9492e89eb5SLei YU /** @brief Check i2c adapter read functionality 9592e89eb5SLei YU * 9692e89eb5SLei YU * Check if the i2c adapter has the functionality specified by the SMBus 9792e89eb5SLei YU * transaction type 9892e89eb5SLei YU * 9992e89eb5SLei YU * @param[in] type - The SMBus transaction type defined in linux/i2c.h 10092e89eb5SLei YU * 10192e89eb5SLei YU * @throw I2CException if the function is not supported 10292e89eb5SLei YU */ 10392e89eb5SLei YU void checkReadFuncs(int type); 10492e89eb5SLei YU 10534fb8bdaSLei YU /** @brief Check i2c adapter write functionality 10634fb8bdaSLei YU * 10734fb8bdaSLei YU * Check if the i2c adapter has the functionality specified by the SMBus 10834fb8bdaSLei YU * transaction type 10934fb8bdaSLei YU * 11034fb8bdaSLei YU * @param[in] type - The SMBus transaction type defined in linux/i2c.h 11134fb8bdaSLei YU * 11234fb8bdaSLei YU * @throw I2CException if the function is not supported 11334fb8bdaSLei YU */ 11434fb8bdaSLei YU void checkWriteFuncs(int type); 11534fb8bdaSLei YU 116ab1327c3SLei YU public: 117d45a9a6dSShawn McCarney /** @copydoc I2CInterface::~I2CInterface() */ 1189af82a5cSLei YU ~I2CDevice() 1199af82a5cSLei YU { 120d45a9a6dSShawn McCarney if (isOpen()) 121d45a9a6dSShawn McCarney { 122d45a9a6dSShawn McCarney // Note: destructors must not throw exceptions 123d45a9a6dSShawn McCarney closeWithoutException(); 1249af82a5cSLei YU } 125d45a9a6dSShawn McCarney } 126d45a9a6dSShawn McCarney 127d45a9a6dSShawn McCarney /** @copydoc I2CInterface::open() */ 128d45a9a6dSShawn McCarney void open(); 129d45a9a6dSShawn McCarney 130d45a9a6dSShawn McCarney /** @copydoc I2CInterface::isOpen() */ 131d45a9a6dSShawn McCarney bool isOpen() const 132d45a9a6dSShawn McCarney { 133d45a9a6dSShawn McCarney return (fd != INVALID_FD); 134d45a9a6dSShawn McCarney } 135d45a9a6dSShawn McCarney 136d45a9a6dSShawn McCarney /** @copydoc I2CInterface::close() */ 137d45a9a6dSShawn McCarney void close(); 138ab1327c3SLei YU 139ab1327c3SLei YU /** @copydoc I2CInterface::read(uint8_t&) */ 140ab1327c3SLei YU void read(uint8_t& data) override; 141ab1327c3SLei YU 142ab1327c3SLei YU /** @copydoc I2CInterface::read(uint8_t,uint8_t&) */ 143ab1327c3SLei YU void read(uint8_t addr, uint8_t& data) override; 144ab1327c3SLei YU 145ab1327c3SLei YU /** @copydoc I2CInterface::read(uint8_t,uint16_t&) */ 146ab1327c3SLei YU void read(uint8_t addr, uint16_t& data) override; 147ab1327c3SLei YU 1481d103428SLei YU /** @copydoc I2CInterface::read(uint8_t,uint8_t&,uint8_t*,Mode) */ 1491d103428SLei YU void read(uint8_t addr, uint8_t& size, uint8_t* data, 1501d103428SLei YU Mode mode = Mode::SMBUS) override; 151ab1327c3SLei YU 152ab1327c3SLei YU /** @copydoc I2CInterface::write(uint8_t) */ 153ab1327c3SLei YU void write(uint8_t data) override; 154ab1327c3SLei YU 155ab1327c3SLei YU /** @copydoc I2CInterface::write(uint8_t,uint8_t) */ 156ab1327c3SLei YU void write(uint8_t addr, uint8_t data) override; 157ab1327c3SLei YU 158ab1327c3SLei YU /** @copydoc I2CInterface::write(uint8_t,uint16_t) */ 159ab1327c3SLei YU void write(uint8_t addr, uint16_t data) override; 160ab1327c3SLei YU 1611d103428SLei YU /** @copydoc I2CInterface::write(uint8_t,uint8_t,const uint8_t*,Mode) */ 1621d103428SLei YU void write(uint8_t addr, uint8_t size, const uint8_t* data, 1631d103428SLei YU Mode mode = Mode::SMBUS) override; 164ab1327c3SLei YU 165ab1327c3SLei YU /** @brief Create an I2CInterface instance 166ab1327c3SLei YU * 167d45a9a6dSShawn McCarney * Automatically opens the I2CInterface if initialState is OPEN. 168d45a9a6dSShawn McCarney * 169ab1327c3SLei YU * @param[in] busId - The i2c bus ID 170ab1327c3SLei YU * @param[in] devAddr - The device address of the i2c 171d45a9a6dSShawn McCarney * @param[in] initialState - Initial state of the I2CInterface object 172*770de580SShawn McCarney * @param[in] maxRetries - Maximum number of times to retry an I2C operation 173ab1327c3SLei YU * 174ab1327c3SLei YU * @return The unique_ptr holding the I2CInterface 175ab1327c3SLei YU */ 176d45a9a6dSShawn McCarney static std::unique_ptr<I2CInterface> 177d45a9a6dSShawn McCarney create(uint8_t busId, uint8_t devAddr, 178*770de580SShawn McCarney InitialState initialState = InitialState::OPEN, 179*770de580SShawn McCarney int maxRetries = 0); 180ab1327c3SLei YU }; 181ab1327c3SLei YU 182ab1327c3SLei YU } // namespace i2c 183