From a2e445cf243e2ba444395776a9efd73ca4d769bb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 9 Dec 2016 12:58:34 +1100 Subject: [PATCH] HAL_Linux: implement set_split_transfers() API for I2C --- libraries/AP_HAL_Linux/I2CDevice.cpp | 10 ++++++++++ libraries/AP_HAL_Linux/I2CDevice.h | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/libraries/AP_HAL_Linux/I2CDevice.cpp b/libraries/AP_HAL_Linux/I2CDevice.cpp index c11fffac66..891074e8d0 100644 --- a/libraries/AP_HAL_Linux/I2CDevice.cpp +++ b/libraries/AP_HAL_Linux/I2CDevice.cpp @@ -154,6 +154,16 @@ I2CDevice::~I2CDevice() bool I2CDevice::transfer(const uint8_t *send, uint32_t send_len, uint8_t *recv, uint32_t recv_len) { + if (send_len > 0 && recv_len > 0 && _split_transfers) { + /* + optionally split all I2C transfers. This is needed for some + devices (such as LidarLite) that require that STOP only + happen with SCL high + */ + return transfer(send, send_len, nullptr, 0) && + transfer(nullptr, 0, recv, recv_len); + } + struct i2c_msg msgs[2] = { }; unsigned nmsgs = 0; diff --git a/libraries/AP_HAL_Linux/I2CDevice.h b/libraries/AP_HAL_Linux/I2CDevice.h index cede381460..0cb5ba829a 100644 --- a/libraries/AP_HAL_Linux/I2CDevice.h +++ b/libraries/AP_HAL_Linux/I2CDevice.h @@ -71,10 +71,16 @@ public: bool adjust_periodic_callback( AP_HAL::Device::PeriodicHandle h, uint32_t period_usec) override; + /* set split transfers flag */ + void set_split_transfers(bool set) override { + _split_transfers = set; + } + protected: I2CBus &_bus; uint8_t _address; uint8_t _retries = 0; + bool _split_transfers = false; }; class I2CDeviceManager : public AP_HAL::I2CDeviceManager {