mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 23:21:54 +00:00 
			
		
		
		
	Fix I2CBus::write() bug and add i2c documentation (#5947)
This commit is contained in:
		
				
					committed by
					
						 Jesse Hills
						Jesse Hills
					
				
			
			
				
	
			
			
			
						parent
						
							7807f0d892
						
					
				
				
					commit
					820f328248
				
			| @@ -11,43 +11,116 @@ namespace i2c { | |||||||
|  |  | ||||||
| #define LOG_I2C_DEVICE(this) ESP_LOGCONFIG(TAG, "  Address: 0x%02X", this->address_); | #define LOG_I2C_DEVICE(this) ESP_LOGCONFIG(TAG, "  Address: 0x%02X", this->address_); | ||||||
|  |  | ||||||
| class I2CDevice; | class I2CDevice;  // forward declaration | ||||||
|  |  | ||||||
|  | /// @brief This class is used to create I2CRegister objects that act as proxies to read/write internal registers on an | ||||||
|  | /// I2C device. | ||||||
|  | /// @details | ||||||
|  | /// @n typical usage: | ||||||
|  | /// @code | ||||||
|  | /// constexpr uint8_t ADDR_REGISTER_1 = 0x12; | ||||||
|  | /// i2c::I2CRegister reg_1 = this->reg(ADDR_REGISTER_1); // declare | ||||||
|  | /// reg_1 |= 0x01; // set bit | ||||||
|  | /// reg_1 &= ~0x01; // reset bit | ||||||
|  | /// reg_1 = 10; // Set value | ||||||
|  | /// uint val = reg_1.get(); // get value | ||||||
|  | /// @endcode | ||||||
|  | /// @details The I²C protocol specifies how to read/write in sets of 8-bits followed by an Acknowledgement (ACK/NACK) | ||||||
|  | /// from the device receiving the data. How the device interprets the bits read/written can vary greatly from | ||||||
|  | /// device to device. However most of the devices follow the same protocol for reading/writing 8 bit registers using as | ||||||
|  | /// implemented in the I2CRegister: after sending the device address, the controller sends one byte with the internal | ||||||
|  | /// register address and then read or write the specified register content. | ||||||
| class I2CRegister { | class I2CRegister { | ||||||
|  public: |  public: | ||||||
|  |   /// @brief overloads the = operator. This allows to set the value of an i2c register | ||||||
|  |   /// @param value value to be set in the register | ||||||
|  |   /// @return pointer to current object | ||||||
|   I2CRegister &operator=(uint8_t value); |   I2CRegister &operator=(uint8_t value); | ||||||
|  |  | ||||||
|  |   /// @brief overloads the compound &= operator. This allows to reset specific bits of an I²C register | ||||||
|  |   /// @param value used for the & operation | ||||||
|  |   /// @return pointer to current object | ||||||
|   I2CRegister &operator&=(uint8_t value); |   I2CRegister &operator&=(uint8_t value); | ||||||
|  |  | ||||||
|  |   /// @brief overloads the compound |= operator. This allows to set specific bits of an I²C register | ||||||
|  |   /// @param value used for the & operation | ||||||
|  |   /// @return pointer to current object | ||||||
|   I2CRegister &operator|=(uint8_t value); |   I2CRegister &operator|=(uint8_t value); | ||||||
|  |  | ||||||
|  |   /// @brief overloads the uint8_t() cast operator to return the I²C register value | ||||||
|  |   /// @return pointer to current object | ||||||
|   explicit operator uint8_t() const { return get(); } |   explicit operator uint8_t() const { return get(); } | ||||||
|  |  | ||||||
|  |   /// @brief returns the register value | ||||||
|  |   /// @return the register value | ||||||
|   uint8_t get() const; |   uint8_t get() const; | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   friend class I2CDevice; |   friend class I2CDevice; | ||||||
|  |  | ||||||
|  |   /// @brief protected constructor that stores the owning object and the register address. Note as only friends can | ||||||
|  |   /// create an I2CRegister @see I2CDevice::reg() | ||||||
|  |   /// @param parent our parent | ||||||
|  |   /// @param a_register address of the i2c register | ||||||
|   I2CRegister(I2CDevice *parent, uint8_t a_register) : parent_(parent), register_(a_register) {} |   I2CRegister(I2CDevice *parent, uint8_t a_register) : parent_(parent), register_(a_register) {} | ||||||
|  |  | ||||||
|   I2CDevice *parent_; |   I2CDevice *parent_;  ///< I2CDevice object pointer | ||||||
|   uint8_t register_; |   uint8_t register_;   ///< the internal address of the register | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /// @brief This class is used to create I2CRegister16 objects that act as proxies to read/write internal registers | ||||||
|  | /// (specified with a 16 bit address) on an I2C device. | ||||||
|  | /// @details | ||||||
|  | /// @n typical usage: | ||||||
|  | /// @code | ||||||
|  | /// constexpr uint16_t X16_BIT_ADDR_REGISTER_1 = 0x1234; | ||||||
|  | /// i2c::I2CRegister16 reg_1 = this->reg16(X16_BIT_ADDR_REGISTER_1); // declare | ||||||
|  | /// reg_1 |= 0x01; // set bit | ||||||
|  | /// reg_1 &= ~0x01; // reset bit | ||||||
|  | /// reg_1 = 10; // Set value | ||||||
|  | /// uint val = reg_1.get(); // get value | ||||||
|  | /// @endcode | ||||||
|  | /// @details The I²C protocol specification, reads/writes in sets of 8-bits followed by an Acknowledgement (ACK/NACK) | ||||||
|  | /// from the device receiving the data. How the device interprets the bits read/written to it can vary greatly from | ||||||
|  | /// device to device. This class can be used to access in the device 8 bits registers that uses a 16 bits internal | ||||||
|  | /// address. After sending the device address, the controller sends the internal register address (using two consecutive | ||||||
|  | /// bytes following the big indian convention) and then read or write the register content. | ||||||
| class I2CRegister16 { | class I2CRegister16 { | ||||||
|  public: |  public: | ||||||
|  |   /// @brief overloads the = operator. This allows to set the value of an I²C register | ||||||
|  |   /// @param value value to be set in the register | ||||||
|  |   /// @return pointer to current object | ||||||
|   I2CRegister16 &operator=(uint8_t value); |   I2CRegister16 &operator=(uint8_t value); | ||||||
|  |  | ||||||
|  |   /// @brief overloads the compound &= operator. This allows to reset specific bits of an I²C register | ||||||
|  |   /// @param value used for the & operation | ||||||
|  |   /// @return pointer to current object | ||||||
|   I2CRegister16 &operator&=(uint8_t value); |   I2CRegister16 &operator&=(uint8_t value); | ||||||
|  |  | ||||||
|  |   /// @brief overloads the compound |= operator. This allows to set bits of an I²C register | ||||||
|  |   /// @param value used for the & operation | ||||||
|  |   /// @return pointer to current object | ||||||
|   I2CRegister16 &operator|=(uint8_t value); |   I2CRegister16 &operator|=(uint8_t value); | ||||||
|  |  | ||||||
|  |   /// @brief overloads the uint8_t() cast operator to return the I²C register value | ||||||
|  |   /// @return the register value | ||||||
|   explicit operator uint8_t() const { return get(); } |   explicit operator uint8_t() const { return get(); } | ||||||
|  |  | ||||||
|  |   /// @brief returns the register value | ||||||
|  |   /// @return the register value | ||||||
|   uint8_t get() const; |   uint8_t get() const; | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   friend class I2CDevice; |   friend class I2CDevice; | ||||||
|  |  | ||||||
|  |   /// @brief protected constructor that store the owning object and the register address. Only friends can create an | ||||||
|  |   /// I2CRegister16 @see I2CDevice::reg16() | ||||||
|  |   /// @param parent our parent | ||||||
|  |   /// @param a_register 16 bits address of the i2c register | ||||||
|   I2CRegister16(I2CDevice *parent, uint16_t a_register) : parent_(parent), register_(a_register) {} |   I2CRegister16(I2CDevice *parent, uint16_t a_register) : parent_(parent), register_(a_register) {} | ||||||
|  |  | ||||||
|   I2CDevice *parent_; |   I2CDevice *parent_;  ///< I2CDevice object pointer | ||||||
|   uint16_t register_; |   uint16_t register_;  ///< the internal 16 bits address of the register | ||||||
| }; | }; | ||||||
|  |  | ||||||
| // like ntohs/htons but without including networking headers. | // like ntohs/htons but without including networking headers. | ||||||
| @@ -55,29 +128,91 @@ class I2CRegister16 { | |||||||
| inline uint16_t i2ctohs(uint16_t i2cshort) { return convert_big_endian(i2cshort); } | inline uint16_t i2ctohs(uint16_t i2cshort) { return convert_big_endian(i2cshort); } | ||||||
| inline uint16_t htoi2cs(uint16_t hostshort) { return convert_big_endian(hostshort); } | inline uint16_t htoi2cs(uint16_t hostshort) { return convert_big_endian(hostshort); } | ||||||
|  |  | ||||||
|  | /// @brief This Class provides the methods to read/write bytes from/to an i2c device. | ||||||
|  | /// Objects keep a list of devices found on bus as well as a pointer to the I2CBus in use. | ||||||
| class I2CDevice { | class I2CDevice { | ||||||
|  public: |  public: | ||||||
|  |   /// @brief we use the C++ default constructor | ||||||
|   I2CDevice() = default; |   I2CDevice() = default; | ||||||
|  |  | ||||||
|  |   /// @brief We store the address of the device on the bus | ||||||
|  |   /// @param address of the device | ||||||
|   void set_i2c_address(uint8_t address) { address_ = address; } |   void set_i2c_address(uint8_t address) { address_ = address; } | ||||||
|  |  | ||||||
|  |   /// @brief we store the pointer to the I2CBus to use | ||||||
|  |   /// @param bus pointer to the I2CBus object | ||||||
|   void set_i2c_bus(I2CBus *bus) { bus_ = bus; } |   void set_i2c_bus(I2CBus *bus) { bus_ = bus; } | ||||||
|  |  | ||||||
|  |   /// @brief calls the I2CRegister constructor | ||||||
|  |   /// @param a_register address of the I²C register | ||||||
|  |   /// @return an I2CRegister proxy object | ||||||
|   I2CRegister reg(uint8_t a_register) { return {this, a_register}; } |   I2CRegister reg(uint8_t a_register) { return {this, a_register}; } | ||||||
|  |  | ||||||
|  |   /// @brief calls the I2CRegister16 constructor | ||||||
|  |   /// @param a_register 16 bits address of the I²C register | ||||||
|  |   /// @return an I2CRegister16 proxy object | ||||||
|   I2CRegister16 reg16(uint16_t a_register) { return {this, a_register}; } |   I2CRegister16 reg16(uint16_t a_register) { return {this, a_register}; } | ||||||
|  |  | ||||||
|  |   /// @brief reads an array of bytes from the device using an I2CBus | ||||||
|  |   /// @param data pointer to an array to store the bytes | ||||||
|  |   /// @param len length of the buffer = number of bytes to read | ||||||
|  |   /// @return an i2c::ErrorCode | ||||||
|   ErrorCode read(uint8_t *data, size_t len) { return bus_->read(address_, data, len); } |   ErrorCode read(uint8_t *data, size_t len) { return bus_->read(address_, data, len); } | ||||||
|  |  | ||||||
|  |   /// @brief reads an array of bytes from a specific register in the I²C device | ||||||
|  |   /// @param a_register an 8 bits internal address of the I²C register to read from | ||||||
|  |   /// @param data pointer to an array to store the bytes | ||||||
|  |   /// @param len length of the buffer = number of bytes to read | ||||||
|  |   /// @param stop (true/false): True will send a stop message, releasing the bus after | ||||||
|  |   /// transmission. False will send a restart, keeping the connection active. | ||||||
|  |   /// @return an i2c::ErrorCode | ||||||
|   ErrorCode read_register(uint8_t a_register, uint8_t *data, size_t len, bool stop = true); |   ErrorCode read_register(uint8_t a_register, uint8_t *data, size_t len, bool stop = true); | ||||||
|  |  | ||||||
|  |   /// @brief reads an array of bytes from a specific register in the I²C device | ||||||
|  |   /// @param a_register the 16 bits internal address of the I²C register to read from | ||||||
|  |   /// @param data pointer to an array of bytes to store the information | ||||||
|  |   /// @param len length of the buffer = number of bytes to read | ||||||
|  |   /// @param stop (true/false): True will send a stop message, releasing the bus after | ||||||
|  |   /// transmission. False will send a restart, keeping the connection active. | ||||||
|  |   /// @return an i2c::ErrorCode | ||||||
|   ErrorCode read_register16(uint16_t a_register, uint8_t *data, size_t len, bool stop = true); |   ErrorCode read_register16(uint16_t a_register, uint8_t *data, size_t len, bool stop = true); | ||||||
|  |  | ||||||
|   ErrorCode write(const uint8_t *data, uint8_t len, bool stop = true) { return bus_->write(address_, data, len, stop); } |   /// @brief writes an array of bytes to a device using an I2CBus | ||||||
|  |   /// @param data pointer to an array that contains the bytes to send | ||||||
|  |   /// @param len length of the buffer = number of bytes to write | ||||||
|  |   /// @param stop (true/false): True will send a stop message, releasing the bus after | ||||||
|  |   /// transmission. False will send a restart, keeping the connection active. | ||||||
|  |   /// @return an i2c::ErrorCode | ||||||
|  |   ErrorCode write(const uint8_t *data, size_t len, bool stop = true) { return bus_->write(address_, data, len, stop); } | ||||||
|  |  | ||||||
|  |   /// @brief writes an array of bytes to a specific register in the I²C device | ||||||
|  |   /// @param a_register the internal address of the register to read from | ||||||
|  |   /// @param data pointer to an array to store the bytes | ||||||
|  |   /// @param len length of the buffer = number of bytes to read | ||||||
|  |   /// @param stop (true/false): True will send a stop message, releasing the bus after | ||||||
|  |   /// transmission. False will send a restart, keeping the connection active. | ||||||
|  |   /// @return an i2c::ErrorCode | ||||||
|   ErrorCode write_register(uint8_t a_register, const uint8_t *data, size_t len, bool stop = true); |   ErrorCode write_register(uint8_t a_register, const uint8_t *data, size_t len, bool stop = true); | ||||||
|  |  | ||||||
|  |   /// @brief write an array of bytes to a specific register in the I²C device | ||||||
|  |   /// @param a_register the 16 bits internal address of the register to read from | ||||||
|  |   /// @param data pointer to an array to store the bytes | ||||||
|  |   /// @param len length of the buffer = number of bytes to read | ||||||
|  |   /// @param stop (true/false): True will send a stop message, releasing the bus after | ||||||
|  |   /// transmission. False will send a restart, keeping the connection active. | ||||||
|  |   /// @return an i2c::ErrorCode | ||||||
|   ErrorCode write_register16(uint16_t a_register, const uint8_t *data, size_t len, bool stop = true); |   ErrorCode write_register16(uint16_t a_register, const uint8_t *data, size_t len, bool stop = true); | ||||||
|  |  | ||||||
|   // Compat APIs |   /// | ||||||
|  |   /// Compat APIs | ||||||
|  |   /// All methods below have been added for compatibility reasons. They do not bring any functionality and therefore on | ||||||
|  |   /// new code it is not recommend to use them. | ||||||
|  |   /// | ||||||
|  |  | ||||||
|   bool read_bytes(uint8_t a_register, uint8_t *data, uint8_t len) { |   bool read_bytes(uint8_t a_register, uint8_t *data, uint8_t len) { | ||||||
|     return read_register(a_register, data, len) == ERROR_OK; |     return read_register(a_register, data, len) == ERROR_OK; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   bool read_bytes_raw(uint8_t *data, uint8_t len) { return read(data, len) == ERROR_OK; } |   bool read_bytes_raw(uint8_t *data, uint8_t len) { return read(data, len) == ERROR_OK; } | ||||||
|  |  | ||||||
|   template<size_t N> optional<std::array<uint8_t, N>> read_bytes(uint8_t a_register) { |   template<size_t N> optional<std::array<uint8_t, N>> read_bytes(uint8_t a_register) { | ||||||
| @@ -131,8 +266,8 @@ class I2CDevice { | |||||||
|   bool write_byte_16(uint8_t a_register, uint16_t data) { return write_bytes_16(a_register, &data, 1); } |   bool write_byte_16(uint8_t a_register, uint16_t data) { return write_bytes_16(a_register, &data, 1); } | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   uint8_t address_{0x00}; |   uint8_t address_{0x00};  ///< store the address of the device on the bus | ||||||
|   I2CBus *bus_{nullptr}; |   I2CBus *bus_{nullptr};   ///< pointer to I2CBus instance | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }  // namespace i2c | }  // namespace i2c | ||||||
|   | |||||||
| @@ -7,50 +7,93 @@ | |||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace i2c { | namespace i2c { | ||||||
|  |  | ||||||
|  | /// @brief Error codes returned by I2CBus and I2CDevice methods | ||||||
| enum ErrorCode { | enum ErrorCode { | ||||||
|   ERROR_OK = 0, |   NO_ERROR = 0,                ///< No error found during execution of method | ||||||
|   ERROR_INVALID_ARGUMENT = 1, |   ERROR_OK = 0,                ///< No error found during execution of method | ||||||
|   ERROR_NOT_ACKNOWLEDGED = 2, |   ERROR_INVALID_ARGUMENT = 1,  ///< method called invalid argument(s) | ||||||
|   ERROR_TIMEOUT = 3, |   ERROR_NOT_ACKNOWLEDGED = 2,  ///< I2C bus acknowledgment not received | ||||||
|   ERROR_NOT_INITIALIZED = 4, |   ERROR_TIMEOUT = 3,           ///< timeout while waiting to receive bytes | ||||||
|   ERROR_TOO_LARGE = 5, |   ERROR_NOT_INITIALIZED = 4,   ///< call method to a not initialized bus | ||||||
|   ERROR_UNKNOWN = 6, |   ERROR_TOO_LARGE = 5,         ///< requested a transfer larger than buffers can hold | ||||||
|   ERROR_CRC = 7, |   ERROR_UNKNOWN = 6,           ///< miscellaneous I2C error during execution | ||||||
|  |   ERROR_CRC = 7,               ///< bytes received with a CRC error | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /// @brief the ReadBuffer structure stores a pointer to a read buffer and its length | ||||||
| struct ReadBuffer { | struct ReadBuffer { | ||||||
|   uint8_t *data; |   uint8_t *data;  ///< pointer to the read buffer | ||||||
|   size_t len; |   size_t len;     ///< length of the buffer | ||||||
| }; |  | ||||||
| struct WriteBuffer { |  | ||||||
|   const uint8_t *data; |  | ||||||
|   size_t len; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /// @brief the WriteBuffer structure stores a pointer to a write buffer and its length | ||||||
|  | struct WriteBuffer { | ||||||
|  |   const uint8_t *data;  ///< pointer to the write buffer | ||||||
|  |   size_t len;           ///< length of the buffer | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /// @brief This Class provides the methods to read and write bytes from an I2CBus. | ||||||
|  | /// @note The I2CBus virtual class follows a *Factory design pattern* that provides all the interfaces methods required | ||||||
|  | /// by clients while deferring the actual implementation of these methods to a subclasses. I2C-bus specification and | ||||||
|  | /// user manual can be found here https://www.nxp.com/docs/en/user-guide/UM10204.pdf and an interesting I²C Application | ||||||
|  | /// note https://www.nxp.com/docs/en/application-note/AN10216.pdf | ||||||
| class I2CBus { | class I2CBus { | ||||||
|  public: |  public: | ||||||
|  |   /// @brief Creates a ReadBuffer and calls the virtual readv() method to read bytes into this buffer | ||||||
|  |   /// @param address address of the I²C component on the i2c bus | ||||||
|  |   /// @param buffer pointer to an array of bytes that will be used to store the data received | ||||||
|  |   /// @param len length of the buffer = number of bytes to read | ||||||
|  |   /// @return an i2c::ErrorCode | ||||||
|   virtual ErrorCode read(uint8_t address, uint8_t *buffer, size_t len) { |   virtual ErrorCode read(uint8_t address, uint8_t *buffer, size_t len) { | ||||||
|     ReadBuffer buf; |     ReadBuffer buf; | ||||||
|     buf.data = buffer; |     buf.data = buffer; | ||||||
|     buf.len = len; |     buf.len = len; | ||||||
|     return readv(address, &buf, 1); |     return readv(address, &buf, 1); | ||||||
|   } |   } | ||||||
|   virtual ErrorCode readv(uint8_t address, ReadBuffer *buffers, size_t cnt) = 0; |  | ||||||
|  |   /// @brief This virtual method reads bytes from an I2CBus into an array of ReadBuffer. | ||||||
|  |   /// @param address address of the I²C component on the i2c bus | ||||||
|  |   /// @param buffers pointer to an array of ReadBuffer | ||||||
|  |   /// @param count number of ReadBuffer to read | ||||||
|  |   /// @return an i2c::ErrorCode | ||||||
|  |   /// @details This is a pure virtual method that must be implemented in a subclass. | ||||||
|  |   virtual ErrorCode readv(uint8_t address, ReadBuffer *buffers, size_t count) = 0; | ||||||
|  |  | ||||||
|   virtual ErrorCode write(uint8_t address, const uint8_t *buffer, size_t len) { |   virtual ErrorCode write(uint8_t address, const uint8_t *buffer, size_t len) { | ||||||
|     return write(address, buffer, len, true); |     return write(address, buffer, len, true); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   /// @brief Creates a WriteBuffer and calls the writev() method to send the bytes from this buffer | ||||||
|  |   /// @param address address of the I²C component on the i2c bus | ||||||
|  |   /// @param buffer pointer to an array of bytes that contains the data to be sent | ||||||
|  |   /// @param len length of the buffer = number of bytes to write | ||||||
|  |   /// @param stop true or false: True will send a stop message, releasing the bus after | ||||||
|  |   /// transmission. False will send a restart, keeping the connection active. | ||||||
|  |   /// @return an i2c::ErrorCode | ||||||
|   virtual ErrorCode write(uint8_t address, const uint8_t *buffer, size_t len, bool stop) { |   virtual ErrorCode write(uint8_t address, const uint8_t *buffer, size_t len, bool stop) { | ||||||
|     WriteBuffer buf; |     WriteBuffer buf; | ||||||
|     buf.data = buffer; |     buf.data = buffer; | ||||||
|     buf.len = len; |     buf.len = len; | ||||||
|     return writev(address, &buf, 1, stop); |     return writev(address, &buf, 1, stop); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   virtual ErrorCode writev(uint8_t address, WriteBuffer *buffers, size_t cnt) { |   virtual ErrorCode writev(uint8_t address, WriteBuffer *buffers, size_t cnt) { | ||||||
|     return writev(address, buffers, cnt, true); |     return writev(address, buffers, cnt, true); | ||||||
|   } |   } | ||||||
|   virtual ErrorCode writev(uint8_t address, WriteBuffer *buffers, size_t cnt, bool stop) = 0; |  | ||||||
|  |   /// @brief This virtual method writes bytes to an I2CBus from an array of WriteBuffer. | ||||||
|  |   /// @param address address of the I²C component on the i2c bus | ||||||
|  |   /// @param buffers pointer to an array of WriteBuffer | ||||||
|  |   /// @param count number of WriteBuffer to write | ||||||
|  |   /// @param stop true or false: True will send a stop message, releasing the bus after | ||||||
|  |   /// transmission. False will send a restart, keeping the connection active. | ||||||
|  |   /// @return an i2c::ErrorCode | ||||||
|  |   /// @details This is a pure virtual method that must be implemented in the subclass. | ||||||
|  |   virtual ErrorCode writev(uint8_t address, WriteBuffer *buffers, size_t count, bool stop) = 0; | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|  |   /// @brief Scans the I2C bus for devices. Devices presence is kept in an array of std::pair | ||||||
|  |   /// that contains the address and the corresponding bool presence flag. | ||||||
|   void i2c_scan_() { |   void i2c_scan_() { | ||||||
|     for (uint8_t address = 8; address < 120; address++) { |     for (uint8_t address = 8; address < 120; address++) { | ||||||
|       auto err = writev(address, nullptr, 0); |       auto err = writev(address, nullptr, 0); | ||||||
| @@ -61,8 +104,8 @@ class I2CBus { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   std::vector<std::pair<uint8_t, bool>> scan_results_; |   std::vector<std::pair<uint8_t, bool>> scan_results_;  ///< array containing scan results | ||||||
|   bool scan_{false}; |   bool scan_{false};                                    ///< Should we scan ? Can be set in the yaml | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }  // namespace i2c | }  // namespace i2c | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user