diff --git a/apps/drivers/device/i2c.cpp b/apps/drivers/device/i2c.cpp index 474190d839..c513ae2b67 100644 --- a/apps/drivers/device/i2c.cpp +++ b/apps/drivers/device/i2c.cpp @@ -166,4 +166,24 @@ I2C::transfer(const uint8_t *send, unsigned send_len, uint8_t *recv, unsigned re } +int +I2C::transfer(i2c_msg_s *msgv, unsigned msgs) +{ + for (unsigned i = 0; i < msgs; i++) + msgv[i].addr = _address; + + /* + * I2C architecture means there is an unavoidable race here + * if there are any devices on the bus with a different frequency + * preference. Really, this is pointless. + */ + I2C_SETFREQUENCY(_dev, _frequency); + ret = I2C_TRANSFER(_dev, msgv, msgs); + + if (ret != OK) + up_i2creset(_dev); + + return ret; +} + } // namespace device \ No newline at end of file diff --git a/apps/drivers/device/i2c.h b/apps/drivers/device/i2c.h index 4d630b8a81..66c34dd7c4 100644 --- a/apps/drivers/device/i2c.h +++ b/apps/drivers/device/i2c.h @@ -100,6 +100,16 @@ protected: int transfer(const uint8_t *send, unsigned send_len, uint8_t *recv, unsigned recv_len); + /** + * Perform a multi-part I2C transaction to the device. + * + * @param msgv An I2C message vector. + * @param msgs The number of entries in the message vector. + * @return OK if the transfer was successful, -errno + * otherwise. + */ + int transfer(i2c_msg_s *msgv, unsigned msgs); + /** * Change the bus address. *