Line data Source code
1 : /*! 2 : * @file I2CController.cpp 3 : * @brief Implementation of the I2CController class. 4 : * @version 0.1 5 : * @date 2025-01-31 6 : * @details This file contains the implementation of the I2CController class, 7 : * which is used to control I2C devices. 8 : * @note This class is used to control I2C devices using the Linux I2C 9 : * interface. 10 : * @author FĂ©lix LE BIHAN (@Fle-bihh) 11 : * @author Tiago Pereira (@t-pereira06) 12 : * @author Ricardo Melo (@reomelo) 13 : * @author Michel Batista (@MicchelFAB) 14 : * @warning Ensure that the I2C device is properly connected and configured. 15 : * @see I2CController.hpp for the class definition. 16 : * @copyright Copyright (c) 2025 17 : */ 18 : 19 : #include "I2CController.hpp" 20 : #include <array> 21 : #include <cstdio> 22 : #include <fcntl.h> 23 : #include <linux/i2c-dev.h> 24 : #include <sys/ioctl.h> 25 : #include <unistd.h> 26 : 27 : /*! 28 : * @brief Construct a new I2CController object. 29 : * @param i2c_device The I2C device to use for communication. 30 : * @param address The I2C address of the device. 31 : * @throws std::runtime_error if the I2C device cannot be opened or the address 32 : * cannot be set. 33 : * @details This constructor initializes the I2CController object with the 34 : * specified I2C device and address. 35 : */ 36 8 : I2CController::I2CController(const char *i2c_device, int address) 37 8 : : i2c_fd_(-1), i2c_addr_(address) { 38 : // Open I2C device 39 8 : i2c_fd_ = open(i2c_device, O_RDWR); 40 8 : if (i2c_fd_ < 0) { 41 1 : perror("Failed to open I2C device"); 42 : } 43 : 44 : // Set I2C address 45 8 : if (ioctl(i2c_fd_, I2C_SLAVE, i2c_addr_) < 0) { 46 1 : perror("Failed to set I2C address"); 47 : } 48 8 : } 49 : 50 : /*! 51 : * @brief Destroy the I2CController object 52 : * @details This destructor closes the I2C device. 53 : */ 54 8 : I2CController::~I2CController() { 55 8 : if (i2c_fd_ >= 0) { 56 7 : close(i2c_fd_); 57 : } 58 8 : } 59 : 60 : /*! 61 : * @brief Write a 16-bit value to a register. 62 : * @param reg The register address to write to. 63 : * @param value The value to write. 64 : * @details This function writes a 16-bit value to a register on the I2C device. 65 : */ 66 2 : void I2CController::writeRegister(uint8_t reg, uint16_t value) { 67 2 : std::array<uint8_t, 3> buffer = {reg, static_cast<uint8_t>(value >> 8), 68 2 : static_cast<uint8_t>(value & 0xFF)}; 69 2 : if (write(i2c_fd_, buffer.data(), buffer.size()) != 3) { 70 1 : perror("I2C write failed"); 71 : } 72 2 : } 73 : 74 : /*! 75 : * @brief Read a 16-bit value from a register. 76 : * @param reg The register address to read from. 77 : * @return uint16_t The value read from the register. 78 : * @details This function reads a 16-bit value from a register on the I2C 79 : * device. 80 : */ 81 3 : uint16_t I2CController::readRegister(uint8_t reg) { 82 3 : if (write(i2c_fd_, ®, 1) != 1) { 83 1 : perror("I2C write failed"); 84 : } 85 : std::array<uint8_t, 2> buffer; 86 3 : if (read(i2c_fd_, buffer.data(), buffer.size()) != 2) { 87 1 : perror("I2C read failed"); 88 : } 89 3 : return (buffer[0] << 8) | buffer[1]; 90 : }