libmems: Add IioDevice::ReadEvents
This commit adds ReadEvents function in IioDevice to read events in
raw.
BUG=chromium:971175
TEST=build with debug code in mems_setup/main.cc and camera/hal_adapter
observe events are retrieved
Change-Id: I79cb477d91e0a4b1fa19d9803b51f036abcedc3b
Reviewed-on: https://chromium-review.googlesource.com/1644833
Tested-by: Cheng-Hao Yang <chenghaoyang@chromium.org>
Commit-Ready: Cheng-Hao Yang <chenghaoyang@chromium.org>
Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org>
Reviewed-by: Heng-ruey Hsu <henryhsu@google.com>
diff --git a/libmems/iio_device_impl.cc b/libmems/iio_device_impl.cc
index 24a497b..8465459 100644
--- a/libmems/iio_device_impl.cc
+++ b/libmems/iio_device_impl.cc
@@ -4,6 +4,7 @@
#include <memory>
#include <string>
+#include <vector>
#include <base/files/file_util.h>
#include <base/logging.h>
@@ -12,10 +13,16 @@
#include "libmems/iio_context_impl.h"
#include "libmems/iio_device_impl.h"
+#define ERROR_BUFFER_SIZE 256
+
namespace libmems {
IioDeviceImpl::IioDeviceImpl(IioContextImpl* ctx, iio_device* dev)
- : IioDevice(), context_(ctx), device_(dev) {
+ : IioDevice(),
+ context_(ctx),
+ device_(dev),
+ buffer_(nullptr, IioBufferDeleter),
+ buffer_size_(0) {
CHECK(context_);
CHECK(device_);
}
@@ -135,6 +142,18 @@
return channels_[name].get();
}
+base::Optional<size_t> IioDeviceImpl::GetSampleSize() const {
+ ssize_t sample_size = iio_device_get_sample_size(device_);
+ if (sample_size < 0) {
+ char errMsg[ERROR_BUFFER_SIZE];
+ iio_strerror(errno, errMsg, sizeof(errMsg));
+ LOG(WARNING) << "Unable to get sample size: " << errMsg;
+ return base::nullopt;
+ }
+
+ return static_cast<size_t>(sample_size);
+}
+
bool IioDeviceImpl::EnableBuffer(size_t count) {
if (!WriteNumberAttribute("buffer/length", count))
return false;
@@ -156,4 +175,71 @@
return enabled;
}
+bool IioDeviceImpl::ReadEvents(uint32_t num_samples,
+ std::vector<uint8_t>* events) {
+ if (!CreateBuffer(num_samples))
+ return false;
+
+ events->clear();
+
+ ssize_t ret = iio_buffer_refill(buffer_.get());
+ if (ret < 0) {
+ char errMsg[ERROR_BUFFER_SIZE];
+ iio_strerror(-ret, errMsg, sizeof(errMsg));
+ LOG(ERROR) << "Unable to refill buffer: " << errMsg;
+ return false;
+ }
+
+ const auto buf_step = iio_buffer_step(buffer_.get());
+ size_t sample_size = GetSampleSize().value_or(0);
+
+ // There is something wrong when refilling the buffer.
+ if (buf_step != sample_size) {
+ LOG(ERROR) << "sample_size doesn't match in refill: " << buf_step
+ << ", sample_size: " << sample_size;
+
+ return false;
+ }
+
+ uint8_t* start = reinterpret_cast<uint8_t*>(iio_buffer_start(buffer_.get()));
+ size_t len = reinterpret_cast<intptr_t>(iio_buffer_end(buffer_.get())) -
+ reinterpret_cast<intptr_t>(start);
+
+ events->reserve(len);
+ events->insert(events->begin(), start, start + len);
+
+ return true;
+}
+
+// static
+void IioDeviceImpl::IioBufferDeleter(iio_buffer* buffer) {
+ iio_buffer_cancel(buffer);
+ iio_buffer_destroy(buffer);
+}
+
+bool IioDeviceImpl::CreateBuffer(uint32_t num_samples) {
+ if (num_samples == 0) {
+ LOG(WARNING) << "Buffer size should not be zero.";
+ return false;
+ }
+
+ if (buffer_ && num_samples == buffer_size_ &&
+ iio_device_get_sample_size(device_) == iio_buffer_step(buffer_.get()))
+ return true;
+
+ buffer_size_ = num_samples;
+
+ buffer_.reset();
+ buffer_.reset(iio_device_create_buffer(device_, num_samples, false));
+
+ if (!buffer_) {
+ char errMsg[ERROR_BUFFER_SIZE];
+ iio_strerror(errno, errMsg, sizeof(errMsg));
+ LOG(ERROR) << "Unable to allocate buffer: " << errMsg;
+ return false;
+ }
+
+ return true;
+}
+
} // namespace libmems