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 229af82a5cSLei YU */ 23d45a9a6dSShawn McCarney explicit I2CDevice(uint8_t busId, uint8_t devAddr, 24d45a9a6dSShawn McCarney InitialState initialState = InitialState::OPEN) : 25d45a9a6dSShawn McCarney busId(busId), 2638ed88d6SShawn McCarney devAddr(devAddr) 27ab1327c3SLei YU { 289af82a5cSLei YU busStr = "/dev/i2c-" + std::to_string(busId); 29d45a9a6dSShawn McCarney if (initialState == InitialState::OPEN) 30d45a9a6dSShawn McCarney { 319af82a5cSLei YU open(); 32ab1327c3SLei YU } 33d45a9a6dSShawn McCarney } 34ab1327c3SLei YU 35d45a9a6dSShawn McCarney /** @brief Invalid file descriptor */ 36d45a9a6dSShawn McCarney static constexpr int INVALID_FD = -1; 379af82a5cSLei YU 3838ed88d6SShawn McCarney /** @brief Empty adapter functionality value with no bit flags set */ 3938ed88d6SShawn McCarney static constexpr unsigned long NO_FUNCS = 0; 4038ed88d6SShawn McCarney 419af82a5cSLei YU /** @brief The I2C bus ID */ 429af82a5cSLei YU uint8_t busId; 439af82a5cSLei YU 449af82a5cSLei YU /** @brief The i2c device address in the bus */ 459af82a5cSLei YU uint8_t devAddr; 469af82a5cSLei YU 479af82a5cSLei YU /** @brief The file descriptor of the opened i2c device */ 4838ed88d6SShawn McCarney int fd = INVALID_FD; 499af82a5cSLei YU 509af82a5cSLei YU /** @brief The i2c bus path in /dev */ 519af82a5cSLei YU std::string busStr; 529af82a5cSLei YU 5338ed88d6SShawn McCarney /** @brief Cached I2C adapter functionality value */ 5438ed88d6SShawn McCarney unsigned long cachedFuncs = NO_FUNCS; 5538ed88d6SShawn McCarney 56d45a9a6dSShawn McCarney /** @brief Check that device interface is open 57d45a9a6dSShawn McCarney * 58d45a9a6dSShawn McCarney * @throw I2CException if device is not open 59d45a9a6dSShawn McCarney */ 60d45a9a6dSShawn McCarney void checkIsOpen() const 61d45a9a6dSShawn McCarney { 62d45a9a6dSShawn McCarney if (!isOpen()) 63d45a9a6dSShawn McCarney { 64d45a9a6dSShawn McCarney throw I2CException("Device not open", busStr, devAddr); 65d45a9a6dSShawn McCarney } 66d45a9a6dSShawn McCarney } 67d45a9a6dSShawn McCarney 68d45a9a6dSShawn McCarney /** @brief Close device without throwing an exception if an error occurs */ 69d45a9a6dSShawn McCarney void closeWithoutException() noexcept 70d45a9a6dSShawn McCarney { 71d45a9a6dSShawn McCarney try 72d45a9a6dSShawn McCarney { 73d45a9a6dSShawn McCarney close(); 74d45a9a6dSShawn McCarney } 75d45a9a6dSShawn McCarney catch (...) 76*0c9a33d6SAdriana Kobylak {} 77d45a9a6dSShawn McCarney } 78d45a9a6dSShawn McCarney 7938ed88d6SShawn McCarney /** @brief Get I2C adapter functionality 8038ed88d6SShawn McCarney * 8138ed88d6SShawn McCarney * Caches the adapter functionality value since it shouldn't change after 8238ed88d6SShawn McCarney * opening the device. 8338ed88d6SShawn McCarney * 8438ed88d6SShawn McCarney * @throw I2CException on error 8538ed88d6SShawn McCarney * @return Adapter functionality value 8638ed88d6SShawn McCarney */ 8738ed88d6SShawn McCarney unsigned long getFuncs(); 8838ed88d6SShawn McCarney 8992e89eb5SLei YU /** @brief Check i2c adapter read functionality 9092e89eb5SLei YU * 9192e89eb5SLei YU * Check if the i2c adapter has the functionality specified by the SMBus 9292e89eb5SLei YU * transaction type 9392e89eb5SLei YU * 9492e89eb5SLei YU * @param[in] type - The SMBus transaction type defined in linux/i2c.h 9592e89eb5SLei YU * 9692e89eb5SLei YU * @throw I2CException if the function is not supported 9792e89eb5SLei YU */ 9892e89eb5SLei YU void checkReadFuncs(int type); 9992e89eb5SLei YU 10034fb8bdaSLei YU /** @brief Check i2c adapter write functionality 10134fb8bdaSLei YU * 10234fb8bdaSLei YU * Check if the i2c adapter has the functionality specified by the SMBus 10334fb8bdaSLei YU * transaction type 10434fb8bdaSLei YU * 10534fb8bdaSLei YU * @param[in] type - The SMBus transaction type defined in linux/i2c.h 10634fb8bdaSLei YU * 10734fb8bdaSLei YU * @throw I2CException if the function is not supported 10834fb8bdaSLei YU */ 10934fb8bdaSLei YU void checkWriteFuncs(int type); 11034fb8bdaSLei YU 111ab1327c3SLei YU public: 112d45a9a6dSShawn McCarney /** @copydoc I2CInterface::~I2CInterface() */ 1139af82a5cSLei YU ~I2CDevice() 1149af82a5cSLei YU { 115d45a9a6dSShawn McCarney if (isOpen()) 116d45a9a6dSShawn McCarney { 117d45a9a6dSShawn McCarney // Note: destructors must not throw exceptions 118d45a9a6dSShawn McCarney closeWithoutException(); 1199af82a5cSLei YU } 120d45a9a6dSShawn McCarney } 121d45a9a6dSShawn McCarney 122d45a9a6dSShawn McCarney /** @copydoc I2CInterface::open() */ 123d45a9a6dSShawn McCarney void open(); 124d45a9a6dSShawn McCarney 125d45a9a6dSShawn McCarney /** @copydoc I2CInterface::isOpen() */ 126d45a9a6dSShawn McCarney bool isOpen() const 127d45a9a6dSShawn McCarney { 128d45a9a6dSShawn McCarney return (fd != INVALID_FD); 129d45a9a6dSShawn McCarney } 130d45a9a6dSShawn McCarney 131d45a9a6dSShawn McCarney /** @copydoc I2CInterface::close() */ 132d45a9a6dSShawn McCarney void close(); 133ab1327c3SLei YU 134ab1327c3SLei YU /** @copydoc I2CInterface::read(uint8_t&) */ 135ab1327c3SLei YU void read(uint8_t& data) override; 136ab1327c3SLei YU 137ab1327c3SLei YU /** @copydoc I2CInterface::read(uint8_t,uint8_t&) */ 138ab1327c3SLei YU void read(uint8_t addr, uint8_t& data) override; 139ab1327c3SLei YU 140ab1327c3SLei YU /** @copydoc I2CInterface::read(uint8_t,uint16_t&) */ 141ab1327c3SLei YU void read(uint8_t addr, uint16_t& data) override; 142ab1327c3SLei YU 1431d103428SLei YU /** @copydoc I2CInterface::read(uint8_t,uint8_t&,uint8_t*,Mode) */ 1441d103428SLei YU void read(uint8_t addr, uint8_t& size, uint8_t* data, 1451d103428SLei YU Mode mode = Mode::SMBUS) override; 146ab1327c3SLei YU 147ab1327c3SLei YU /** @copydoc I2CInterface::write(uint8_t) */ 148ab1327c3SLei YU void write(uint8_t data) override; 149ab1327c3SLei YU 150ab1327c3SLei YU /** @copydoc I2CInterface::write(uint8_t,uint8_t) */ 151ab1327c3SLei YU void write(uint8_t addr, uint8_t data) override; 152ab1327c3SLei YU 153ab1327c3SLei YU /** @copydoc I2CInterface::write(uint8_t,uint16_t) */ 154ab1327c3SLei YU void write(uint8_t addr, uint16_t data) override; 155ab1327c3SLei YU 1561d103428SLei YU /** @copydoc I2CInterface::write(uint8_t,uint8_t,const uint8_t*,Mode) */ 1571d103428SLei YU void write(uint8_t addr, uint8_t size, const uint8_t* data, 1581d103428SLei YU Mode mode = Mode::SMBUS) override; 159ab1327c3SLei YU 160ab1327c3SLei YU /** @brief Create an I2CInterface instance 161ab1327c3SLei YU * 162d45a9a6dSShawn McCarney * Automatically opens the I2CInterface if initialState is OPEN. 163d45a9a6dSShawn McCarney * 164ab1327c3SLei YU * @param[in] busId - The i2c bus ID 165ab1327c3SLei YU * @param[in] devAddr - The device address of the i2c 166d45a9a6dSShawn McCarney * @param[in] initialState - Initial state of the I2CInterface object 167ab1327c3SLei YU * 168ab1327c3SLei YU * @return The unique_ptr holding the I2CInterface 169ab1327c3SLei YU */ 170d45a9a6dSShawn McCarney static std::unique_ptr<I2CInterface> 171d45a9a6dSShawn McCarney create(uint8_t busId, uint8_t devAddr, 172d45a9a6dSShawn McCarney InitialState initialState = InitialState::OPEN); 173ab1327c3SLei YU }; 174ab1327c3SLei YU 175ab1327c3SLei YU } // namespace i2c 176