[i2c_temperature] Organize components into modules
Separate driver components and libraries into individual directories.
Add method comments and clean up imports.
Change-Id: I515544662b20ba2c9c2f60003fb0ca78b867bf9a
Reviewed-on: https://fuchsia-review.googlesource.com/c/sdk-samples/drivers/+/710245
Reviewed-by: Novin Changizi <novinc@google.com>
Reviewed-by: Sarah Chan <spqchan@google.com>
Reviewed-by: Suraj Malhotra <surajmalhotra@google.com>
Commit-Queue: Dave Smith <smithdave@google.com>
diff --git a/src/BUILD.bazel b/src/BUILD.bazel
index 16f6712..72e4ab0 100644
--- a/src/BUILD.bazel
+++ b/src/BUILD.bazel
@@ -18,8 +18,8 @@
"//src/bind_library:parent_pkg",
"//src/composite_sample:pkg",
"//src/example_driver:pkg",
- "//src/i2c_temperature:pkg",
- "//src/i2c_temperature:test_controller_pkg",
+ "//src/i2c_temperature/controller:pkg",
+ "//src/i2c_temperature/driver:pkg",
"//src/input_sample:pkg",
"//src/qemu_edu/drivers:pkg",
"//src/qemu_edu/tests:pkg",
diff --git a/src/i2c_temperature/BUILD.bazel b/src/i2c_temperature/BUILD.bazel
deleted file mode 100644
index 63cc3c9..0000000
--- a/src/i2c_temperature/BUILD.bazel
+++ /dev/null
@@ -1,140 +0,0 @@
-# Copyright 2022 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-load(
- "@rules_fuchsia//fuchsia:defs.bzl",
- "fuchsia_cc_binary",
- "fuchsia_component_manifest",
- "fuchsia_driver_bytecode_bind_rules",
- "fuchsia_driver_component",
- "fuchsia_fidl_library",
- "fuchsia_fidl_llcpp_library",
- "fuchsia_package",
-)
-
-fuchsia_fidl_library(
- name = "sample.i2ctemperature",
- srcs = [
- "i2c_temperature.fidl",
- ],
- library = "sample.i2ctemperature",
- visibility = ["//visibility:public"],
- deps = [
- "@fuchsia_sdk//fidl/zx:zx",
- ],
-)
-
-fuchsia_fidl_llcpp_library(
- name = "sample.i2ctemperature_cc",
- library = ":sample.i2ctemperature",
- visibility = ["//visibility:public"],
- deps = [
- "@fuchsia_sdk//fidl/zx:zx_llcpp_cc",
- "@fuchsia_sdk//pkg/fidl_cpp_wire",
- ],
-)
-
-fuchsia_driver_bytecode_bind_rules(
- name = "bind_bytecode",
- output = "i2c_temperature.bindbc",
- rules = "i2c_temperature.bind",
- deps = [
- "@fuchsia_sdk//bind/fuchsia.i2c",
- ],
-)
-
-cc_binary(
- name = "i2c_temperature",
- srcs = [
- "constants.h",
- "i2c_channel.cc",
- "i2c_channel.h",
- "i2c_temperature.cc",
- "i2c_temperature.h",
- ],
- linkshared = True,
- deps = [
- ":sample.i2ctemperature_cc",
- "@fuchsia_sdk//fidl/fuchsia.hardware.i2c:fuchsia.hardware.i2c_llcpp_cc",
- "@fuchsia_sdk//fidl/zx:zx_cc",
- "@fuchsia_sdk//pkg/async-cpp",
- "@fuchsia_sdk//pkg/driver2-llcpp",
- "@fuchsia_sdk//pkg/fidl_cpp_wire",
- "@fuchsia_sdk//pkg/sys_component_llcpp",
- "@fuchsia_sdk//pkg/zx",
- ],
-)
-
-fuchsia_component_manifest(
- name = "manifest",
- src = "meta/i2c_temperature.cml",
-)
-
-fuchsia_driver_component(
- name = "component",
- bind_bytecode = ":bind_bytecode",
- driver_lib = ":i2c_temperature",
- manifest = ":manifest",
-)
-
-fuchsia_package(
- name = "pkg",
- package_name = "i2c_temperature",
- visibility = ["//visibility:public"],
- deps = [
- ":component",
- ],
-)
-
-fuchsia_driver_bytecode_bind_rules(
- name = "test_controller_bind_bytecode",
- output = "test_controller.bindbc",
- rules = "test_i2c_controller.bind",
- deps = [
- "@fuchsia_sdk//bind/fuchsia.acpi",
- ],
-)
-
-cc_binary(
- name = "test_controller",
- srcs = [
- "constants.h",
- "test_i2c_controller.cc",
- "test_i2c_controller.h",
- ],
- linkshared = True,
- deps = [
- "@fuchsia_sdk//fidl/fuchsia.device.fs:fuchsia.device.fs_llcpp_cc",
- "@fuchsia_sdk//fidl/fuchsia.driver.compat:fuchsia.driver.compat_llcpp_cc",
- "@fuchsia_sdk//fidl/fuchsia.hardware.i2c:fuchsia.hardware.i2c_llcpp_cc",
- "@fuchsia_sdk//fidl/zx:zx_cc",
- "@fuchsia_sdk//pkg/async-cpp",
- "@fuchsia_sdk//pkg/driver2-llcpp",
- "@fuchsia_sdk//pkg/fidl_cpp_wire",
- "@fuchsia_sdk//pkg/sys_component_llcpp",
- "@fuchsia_sdk//pkg/zx",
- ],
-)
-
-fuchsia_component_manifest(
- name = "test_controller_manifest",
- src = "meta/test_i2c_controller.cml",
-)
-
-fuchsia_driver_component(
- name = "test_controller_component",
- bind_bytecode = ":test_controller_bind_bytecode",
- driver_lib = ":test_controller",
- manifest = ":test_controller_manifest",
-)
-
-fuchsia_package(
- name = "test_controller_pkg",
- package_name = "test_i2c_controller",
- visibility = ["//visibility:public"],
- deps = [
- ":test_controller_component",
- ],
-)
-
diff --git a/src/i2c_temperature/README.md b/src/i2c_temperature/README.md
new file mode 100644
index 0000000..3408cc6
--- /dev/null
+++ b/src/i2c_temperature/README.md
@@ -0,0 +1,60 @@
+# I2C Temperature Sample
+
+This sample project contains a driver component named `i2c_temperature` for a temperature
+sensor device connected to an I2C bus with device address `0xFF`.
+The driver interacts with the device hardware using the `fuchsia.hardware.i2c` protocol,
+and exposes a custom FIDL protocol (`sample.i2ctemperature`) for other components to
+consume.
+
+The `i2c_controller` driver component emulates an I2C bus controller, creating the child
+device nodes to the sensor device and responding to I2C protocol commands received from
+the child devices.
+
+## Building
+
+To build the `i2c_temperature` driver and related components, run the following commands:
+
+```
+tools/bazel build --config=fuchsia_x64 //src/i2c_temperature/controller:pkg
+tools/bazel build --config=fuchsia_x64 //src/i2c_temperature/driver:pkg
+```
+
+## Running
+
+Use the following commands to load the driver components on a target device:
+
+1. Load the `i2c_controller` driver component to create a virtual I2C device node:
+
+ ```
+ tools/bazel run --config=fuchsia_x64 //src/i2c_temperature/controller:pkg.component
+ ```
+
+1. Load the `i2c_temperature` driver component to bind to the device node and begin
+ sending requests:
+
+ ```
+ tools/bazel run --config=fuchsia_x64 //src/i2c_temperature/driver:pkg.component
+ ```
+
+1. Open the device log viewer:
+
+ ```
+ tools/ffx log --filter i2c_controller --filter i2c_temperature
+ ```
+
+You should see the `i2c_controller` driver log the requests it receives from `i2c_temperature`
+after the driver has successfully bound.
+
+```
+[i2c-temperature-controller,driver][I]: [i2c_controller.cc:139] Received transfer request
+[i2c-temperature-controller,driver][I]: [i2c_controller.cc:126] Reset command received
+[i2c-temperature-controller,driver][I]: [i2c_controller.cc:139] Received transfer request
+[i2c-temperature,driver][I]: [i2c_temperature.cc:62] I2C temperature: temperature=20
+```
+
+## Source layout
+
+* `controller/` — Source code of the `i2c_controller` driver component.
+* `driver/` — Source code of the `i2c_temperature` driver component.
+* `fidl/` — FIDL library definition for `sample.i2ctemperature`.
+* `lib/` — Common I2C constants shared between the controller and driver components.
diff --git a/src/i2c_temperature/controller/BUILD.bazel b/src/i2c_temperature/controller/BUILD.bazel
new file mode 100644
index 0000000..4d7f828
--- /dev/null
+++ b/src/i2c_temperature/controller/BUILD.bazel
@@ -0,0 +1,71 @@
+# Copyright 2022 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+load(
+ "@rules_fuchsia//fuchsia:defs.bzl",
+ "fuchsia_cc_binary",
+ "fuchsia_component_manifest",
+ "fuchsia_driver_bytecode_bind_rules",
+ "fuchsia_driver_component",
+ "fuchsia_package",
+)
+
+# [START bind_rules]
+fuchsia_driver_bytecode_bind_rules(
+ name = "bind_bytecode",
+ output = "i2c_controller.bindbc",
+ rules = "i2c_controller.bind",
+ deps = [
+ "@fuchsia_sdk//bind/fuchsia.acpi",
+ ],
+)
+# [END bind_rules]
+
+# [START cc_binary]
+cc_binary(
+ name = "i2c_controller",
+ srcs = [
+ "i2c_controller.cc",
+ "i2c_controller.h",
+ ],
+ linkshared = True,
+ deps = [
+ "//src/i2c_temperature/lib",
+ "@fuchsia_sdk//fidl/fuchsia.device.fs:fuchsia.device.fs_llcpp_cc",
+ "@fuchsia_sdk//fidl/fuchsia.driver.compat:fuchsia.driver.compat_llcpp_cc",
+ "@fuchsia_sdk//fidl/fuchsia.hardware.i2c:fuchsia.hardware.i2c_bindlib_cc",
+ "@fuchsia_sdk//fidl/fuchsia.hardware.i2c:fuchsia.hardware.i2c_llcpp_cc",
+ "@fuchsia_sdk//fidl/zx:zx_cc",
+ "@fuchsia_sdk//pkg/async-cpp",
+ "@fuchsia_sdk//pkg/driver2-llcpp",
+ "@fuchsia_sdk//pkg/fidl_cpp_wire",
+ "@fuchsia_sdk//pkg/sys_component_llcpp",
+ "@fuchsia_sdk//pkg/zx",
+ ],
+)
+# [END cc_binary]
+
+fuchsia_component_manifest(
+ name = "manifest",
+ src = "meta/i2c_controller.cml",
+ includes = [
+ "@fuchsia_sdk//pkg/syslog:client",
+ ],
+)
+
+fuchsia_driver_component(
+ name = "component",
+ bind_bytecode = ":bind_bytecode",
+ driver_lib = ":i2c_controller",
+ manifest = ":manifest",
+)
+
+fuchsia_package(
+ name = "pkg",
+ package_name = "i2c_controller",
+ visibility = ["//visibility:public"],
+ deps = [
+ ":component",
+ ],
+)
diff --git a/src/i2c_temperature/test_i2c_controller.bind b/src/i2c_temperature/controller/i2c_controller.bind
similarity index 100%
rename from src/i2c_temperature/test_i2c_controller.bind
rename to src/i2c_temperature/controller/i2c_controller.bind
diff --git a/src/i2c_temperature/controller/i2c_controller.cc b/src/i2c_temperature/controller/i2c_controller.cc
new file mode 100644
index 0000000..d2e0010
--- /dev/null
+++ b/src/i2c_temperature/controller/i2c_controller.cc
@@ -0,0 +1,200 @@
+// Copyright 2022 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "i2c_controller.h"
+
+#include <endian.h>
+#include <fidl/fuchsia.component.decl/cpp/wire.h>
+#include <lib/driver2/record_cpp.h>
+
+// [START bind_imports]
+#include <bind/fuchsia/hardware/i2c/cpp/bind.h>
+// [END bind_imports]
+
+#include "constants.h"
+
+namespace i2c_temperature {
+
+namespace {
+
+constexpr uint32_t kStartingTemp = 20;
+constexpr uint32_t kTempIncrement = 5;
+
+} // namespace
+
+zx::status<std::unique_ptr<I2cTemperatureController>> I2cTemperatureController::Start(
+ fuchsia_driver_framework::wire::DriverStartArgs& start_args, fdf::UnownedDispatcher dispatcher,
+ fidl::WireSharedClient<fuchsia_driver_framework::Node> node, driver::Namespace ns,
+ driver::Logger logger) {
+ auto driver = std::make_unique<I2cTemperatureController>(
+ dispatcher->async_dispatcher(), std::move(node), std::move(ns), std::move(logger));
+ auto result = driver->Run(std::move(start_args.outgoing_dir()));
+ if (result.is_error()) {
+ return result.take_error();
+ }
+
+ return zx::ok(std::move(driver));
+}
+
+zx::status<> I2cTemperatureController::Run(fidl::ServerEnd<fuchsia_io::Directory> outgoing_dir) {
+ temperature_ = kStartingTemp;
+
+ auto service = [this](fidl::ServerEnd<fuchsia_hardware_i2c::Device> server_end) {
+ fidl::BindServer(dispatcher_, std::move(server_end), this);
+ };
+
+ auto status = outgoing_.AddProtocol<fuchsia_hardware_i2c::Device>(std::move(service));
+ if (status.status_value() != ZX_OK) {
+ FDF_SLOG(ERROR, "Failed to add protocol", KV("status", status.status_string()));
+ return status;
+ }
+
+ status = AddChild();
+ if (status.status_value() != ZX_OK) {
+ return status;
+ }
+
+ return outgoing_.Serve(std::move(outgoing_dir));
+}
+
+zx::status<> I2cTemperatureController::AddChild() {
+ fidl::Arena arena;
+
+ // [START add_child_offer]
+ // Offer `fuchsia.hardware.i2c.Device` to the driver that binds to the node.
+ auto protocol_offer =
+ fuchsia_component_decl::wire::OfferProtocol::Builder(arena)
+ .source_name(arena, fidl::DiscoverableProtocolName<fuchsia_hardware_i2c::Device>)
+ .target_name(arena, fidl::DiscoverableProtocolName<fuchsia_hardware_i2c::Device>)
+ .dependency_type(fuchsia_component_decl::wire::DependencyType::kStrong)
+ .Build();
+ fuchsia_component_decl::wire::Offer offer =
+ fuchsia_component_decl::wire::Offer::WithProtocol(arena, protocol_offer);
+ // [END add_child_offer]
+
+ // [START add_child_properties]
+ // Set the properties of the node that a driver will bind to.
+ auto properties = fidl::VectorView<fuchsia_driver_framework::wire::NodeProperty>(arena, 2);
+ properties[0] = fuchsia_driver_framework::wire::NodeProperty::Builder(arena)
+ .key(fuchsia_driver_framework::wire::NodePropertyKey::WithStringValue(
+ arena, bind_fuchsia_hardware_i2c::DEVICE))
+ .value(fuchsia_driver_framework::wire::NodePropertyValue::WithEnumValue(
+ arena, bind_fuchsia_hardware_i2c::DEVICE_ZIRCONTRANSPORT))
+ .Build();
+ properties[1] = fuchsia_driver_framework::wire::NodeProperty::Builder(arena)
+ .key(fuchsia_driver_framework::wire::NodePropertyKey::WithIntValue(
+ 0x0A02 /* BIND_I2C_ADDRESS */))
+ .value(fuchsia_driver_framework::wire::NodePropertyValue::WithIntValue(0xff))
+ .Build();
+
+ auto args =
+ fuchsia_driver_framework::wire::NodeAddArgs::Builder(arena)
+ .name(arena, "i2c-child")
+ .offers(fidl::VectorView<fuchsia_component_decl::wire::Offer>::FromExternal(&offer, 1))
+ .properties(properties)
+ .Build();
+ // [END add_child_properties]
+
+ // [START add_child_node]
+ // Create endpoints of the `NodeController` for the node.
+ auto endpoints = fidl::CreateEndpoints<fuchsia_driver_framework::NodeController>();
+ if (endpoints.is_error()) {
+ FDF_SLOG(ERROR, "Failed to create endpoint", KV("status", endpoints.status_string()));
+ return zx::error(endpoints.status_value());
+ }
+
+ auto result = node_.sync()->AddChild(args, std::move(endpoints->server), {});
+ if (!result.ok()) {
+ FDF_SLOG(ERROR, "Failed to add child", KV("status", result.status_string()));
+ return zx::error(result.status());
+ }
+ // [END add_child_node]
+
+ return zx::ok();
+}
+
+// Process data transfer WRITE requests. Parse the command from the driver and update:
+// - kSoftResetCommand: Reset internal temperature to initial value
+// - kStartMeasurementCommand: Increment internal temperature value
+void I2cTemperatureController::HandleWrite(const fidl::VectorView<uint8_t> write_data) {
+ // For simplicity, assume only integer commands from I2cTemperatureDriver.
+ if (write_data.count() > 4) {
+ return;
+ }
+
+ // Convert write data from big-endian to local
+ int command;
+ std::memcpy(&command, write_data.data(), sizeof(int));
+ command = be16toh(command);
+
+ if (command == i2c_temperature::kSoftResetCommand) {
+ FDF_SLOG(INFO, "Reset command received");
+ temperature_ = kStartingTemp;
+ } else if (command == i2c_temperature::kStartMeasurementCommand) {
+ FDF_SLOG(INFO, "Measurement command received");
+ temperature_ += kTempIncrement;
+ } else {
+ FDF_SLOG(WARNING, "Received unknown command ", KV("command", command));
+ }
+}
+
+// Protocol method of `fuchsia.hardware.i2c.Device` to handle data transfer requests.
+void I2cTemperatureController::Transfer(TransferRequestView request,
+ TransferCompleter::Sync& completer) {
+ FDF_SLOG(INFO, "Received transfer request");
+
+ if (request->transactions.count() < 1) {
+ completer.ReplyError(ZX_ERR_INVALID_ARGS);
+ return;
+ }
+
+ // Create a vector of read transfers
+ fidl::Arena allocator;
+ std::vector<fidl::VectorView<uint8_t>> read_data;
+
+ for (size_t i = 0; i < request->transactions.count(); ++i) {
+ if (!request->transactions[i].has_data_transfer()) {
+ completer.ReplyError(ZX_ERR_INVALID_ARGS);
+ return;
+ }
+
+ const auto& transfer = request->transactions[i].data_transfer();
+
+ if (transfer.is_write_data()) {
+ // Handle write transaction.
+ if (transfer.write_data().count() <= 0) {
+ completer.ReplyError(ZX_ERR_INVALID_ARGS);
+ return;
+ }
+
+ HandleWrite(transfer.write_data());
+ } else {
+ // Handle read transaction.
+ if (transfer.read_size() <= 0) {
+ completer.ReplyError(ZX_ERR_INVALID_ARGS);
+ return;
+ }
+
+ // Convert read data from local to big-endian
+ auto read_value = htobe16(temperature_);
+ auto read_bytes = fidl::VectorView<uint8_t>(allocator, transfer.read_size());
+ for (size_t i = 0; i < read_bytes.count(); i++) {
+ read_bytes[i] = read_value >> (i * 8) & 0xff;
+ }
+ read_data.push_back(read_bytes);
+ }
+ }
+
+ // Complete the transaction, returning any read data
+ auto read_results = fidl::VectorView<fidl::VectorView<uint8_t>>(allocator, read_data.size());
+ for (size_t i = 0; i < read_data.size(); i++) {
+ read_results[i] = read_data[i];
+ }
+
+ completer.ReplySuccess(read_results);
+}
+
+} // namespace i2c_temperature
+
+FUCHSIA_DRIVER_RECORD_CPP_V1(i2c_temperature::I2cTemperatureController);
diff --git a/src/i2c_temperature/controller/i2c_controller.h b/src/i2c_temperature/controller/i2c_controller.h
new file mode 100644
index 0000000..15382e0
--- /dev/null
+++ b/src/i2c_temperature/controller/i2c_controller.h
@@ -0,0 +1,64 @@
+// Copyright 2022 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FUCHSIA_SDK_EXAMPLES_SRC_I2C_TEMPERATURE_I2C_CONTROLLER_H_
+#define FUCHSIA_SDK_EXAMPLES_SRC_I2C_TEMPERATURE_I2C_CONTROLLER_H_
+
+#include <fidl/fuchsia.driver.framework/cpp/wire.h>
+#include <fidl/fuchsia.hardware.i2c/cpp/wire.h>
+#include <lib/async/cpp/executor.h>
+#include <lib/driver2/namespace.h>
+#include <lib/driver2/structured_logger.h>
+#include <lib/fdf/cpp/dispatcher.h>
+#include <lib/sys/component/llcpp/outgoing_directory.h>
+
+namespace i2c_temperature {
+
+// Sample driver that implements a `fuchsia.hardware.i2c` bus controller and emulates the
+// behavior of a temperature sensor device to interact with the i2c temperature driver.
+class I2cTemperatureController : public fidl::WireServer<fuchsia_hardware_i2c::Device> {
+ public:
+ I2cTemperatureController(async_dispatcher_t* dispatcher,
+ fidl::WireSharedClient<fuchsia_driver_framework::Node> node,
+ driver::Namespace ns, driver::Logger logger)
+ : dispatcher_(dispatcher),
+ outgoing_(component::OutgoingDirectory::Create(dispatcher)),
+ ns_(std::move(ns)),
+ logger_(std::move(logger)),
+ node_(std::move(node)) {}
+
+ virtual ~I2cTemperatureController() = default;
+
+ static constexpr const char* Name() { return "i2c-temperature-controller"; }
+
+ static zx::status<std::unique_ptr<I2cTemperatureController>> Start(
+ fuchsia_driver_framework::wire::DriverStartArgs& start_args,
+ fdf::UnownedDispatcher dispatcher,
+ fidl::WireSharedClient<fuchsia_driver_framework::Node> node, driver::Namespace ns,
+ driver::Logger logger);
+
+ // fuchsia.hardware.i2c/Device:
+ void Transfer(TransferRequestView request, TransferCompleter::Sync& completer);
+
+ private:
+ zx::status<> Run(fidl::ServerEnd<fuchsia_io::Directory> outgoing_dir);
+ zx::status<> AddChild();
+
+ void HandleWrite(const fidl::VectorView<uint8_t> write_data);
+
+ uint32_t temperature_;
+
+ async_dispatcher_t* const dispatcher_;
+
+ component::OutgoingDirectory outgoing_;
+ driver::Namespace ns_;
+ driver::Logger logger_;
+
+ fidl::WireSharedClient<fuchsia_driver_framework::Node> node_;
+ fidl::WireSharedClient<fuchsia_driver_framework::NodeController> controller_;
+};
+
+} // namespace i2c_temperature
+
+#endif // FUCHSIA_SDK_EXAMPLES_SRC_I2C_TEMPERATURE_I2C_CONTROLLER_H_
diff --git a/src/i2c_temperature/controller/meta/i2c_controller.cml b/src/i2c_temperature/controller/meta/i2c_controller.cml
new file mode 100644
index 0000000..2f18b9a
--- /dev/null
+++ b/src/i2c_temperature/controller/meta/i2c_controller.cml
@@ -0,0 +1,26 @@
+// Copyright 2022 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+{
+ include: [
+ 'syslog/client.shard.cml',
+ ],
+ program: {
+ runner: 'driver',
+ binary: 'lib/libi2c_controller.so',
+ bind: 'meta/bind/i2c_controller.bindbc'
+ },
+ use: [
+ { service: 'fuchsia.driver.compat.Service' },
+ ],
+ // Provide the I2C device capability to other components
+ capabilities: [
+ { protocol: 'fuchsia.hardware.i2c.Device' },
+ ],
+ expose: [
+ {
+ protocol: 'fuchsia.hardware.i2c.Device',
+ from: 'self',
+ },
+ ],
+}
diff --git a/src/i2c_temperature/driver/BUILD.bazel b/src/i2c_temperature/driver/BUILD.bazel
new file mode 100644
index 0000000..f32682d
--- /dev/null
+++ b/src/i2c_temperature/driver/BUILD.bazel
@@ -0,0 +1,71 @@
+# Copyright 2022 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+load(
+ "@rules_fuchsia//fuchsia:defs.bzl",
+ "fuchsia_cc_binary",
+ "fuchsia_component_manifest",
+ "fuchsia_driver_bytecode_bind_rules",
+ "fuchsia_driver_component",
+ "fuchsia_package",
+)
+
+# [START bind_rules]
+fuchsia_driver_bytecode_bind_rules(
+ name = "bind_bytecode",
+ output = "i2c_temperature.bindbc",
+ rules = "i2c_temperature.bind",
+ deps = [
+ "@fuchsia_sdk//fidl/fuchsia.hardware.i2c:fuchsia.hardware.i2c_bindlib",
+ ],
+)
+# [END bind_rules]
+
+# [START cc_binary]
+cc_binary(
+ name = "i2c_temperature",
+ srcs = [
+ "i2c_channel.cc",
+ "i2c_channel.h",
+ "i2c_temperature.cc",
+ "i2c_temperature.h",
+ ],
+ linkshared = True,
+ deps = [
+ "//src/i2c_temperature/fidl:sample.i2ctemperature_cc",
+ "//src/i2c_temperature/lib",
+ "@fuchsia_sdk//fidl/fuchsia.hardware.i2c:fuchsia.hardware.i2c_llcpp_cc",
+ "@fuchsia_sdk//fidl/zx:zx_cc",
+ "@fuchsia_sdk//pkg/async-cpp",
+ "@fuchsia_sdk//pkg/driver2-llcpp",
+ "@fuchsia_sdk//pkg/fidl_cpp_wire",
+ "@fuchsia_sdk//pkg/sys_component_llcpp",
+ "@fuchsia_sdk//pkg/zx",
+ ],
+)
+# [END cc_binary]
+
+fuchsia_component_manifest(
+ name = "manifest",
+ src = "meta/i2c_temperature.cml",
+ includes = [
+ "@fuchsia_sdk//pkg/syslog:client",
+ ],
+)
+
+fuchsia_driver_component(
+ name = "component",
+ bind_bytecode = ":bind_bytecode",
+ driver_lib = ":i2c_temperature",
+ manifest = ":manifest",
+)
+
+fuchsia_package(
+ name = "pkg",
+ package_name = "i2c_temperature",
+ visibility = ["//visibility:public"],
+ deps = [
+ ":component",
+ ],
+)
diff --git a/src/i2c_temperature/i2c_channel.cc b/src/i2c_temperature/driver/i2c_channel.cc
similarity index 97%
rename from src/i2c_temperature/i2c_channel.cc
rename to src/i2c_temperature/driver/i2c_channel.cc
index 22744da..a711b75 100644
--- a/src/i2c_temperature/i2c_channel.cc
+++ b/src/i2c_temperature/driver/i2c_channel.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "src/i2c_temperature/i2c_channel.h"
+#include "i2c_channel.h"
#include <endian.h>
diff --git a/src/i2c_temperature/i2c_channel.h b/src/i2c_temperature/driver/i2c_channel.h
similarity index 88%
rename from src/i2c_temperature/i2c_channel.h
rename to src/i2c_temperature/driver/i2c_channel.h
index b737369..f753b22 100644
--- a/src/i2c_temperature/i2c_channel.h
+++ b/src/i2c_temperature/driver/i2c_channel.h
@@ -16,8 +16,7 @@
~I2cChannel() = default;
// Functions that perform read/write transactions through the client.
- // The values are converted from big-endian order to host byte order for write
- // and vice versa for read.
+ // The values are transferred across the I2C channel in big-endian order.
zx::status<uint16_t> Read16();
zx::status<> Write16(uint16_t value);
diff --git a/src/i2c_temperature/driver/i2c_temperature.bind b/src/i2c_temperature/driver/i2c_temperature.bind
new file mode 100644
index 0000000..0ea484c
--- /dev/null
+++ b/src/i2c_temperature/driver/i2c_temperature.bind
@@ -0,0 +1,10 @@
+// Copyright 2022 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// [START bind_rules]
+using fuchsia.hardware.i2c;
+
+fuchsia.hardware.i2c.Device == fuchsia.hardware.i2c.Device.ZirconTransport;
+fuchsia.BIND_I2C_ADDRESS == 0xFF;
+// [END bind_rules]
diff --git a/src/i2c_temperature/i2c_temperature.cc b/src/i2c_temperature/driver/i2c_temperature.cc
similarity index 72%
rename from src/i2c_temperature/i2c_temperature.cc
rename to src/i2c_temperature/driver/i2c_temperature.cc
index 1e77aa7..d7de4d6 100644
--- a/src/i2c_temperature/i2c_temperature.cc
+++ b/src/i2c_temperature/driver/i2c_temperature.cc
@@ -2,13 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "src/i2c_temperature/i2c_temperature.h"
+#include "i2c_temperature.h"
#include <lib/driver2/record_cpp.h>
-#include "src/i2c_temperature/constants.h"
-
-namespace fio = fuchsia_io;
+#include "constants.h"
namespace i2c_temperature {
@@ -27,27 +25,46 @@
return zx::ok(std::move(driver));
}
-zx::status<> I2cTemperatureDriver::Run(fidl::ServerEnd<fio::Directory> outgoing_dir) {
+zx::status<> I2cTemperatureDriver::Run(fidl::ServerEnd<fuchsia_io::Directory> outgoing_dir) {
+ // Serve the `sample.i2ctemperature` protocol to clients
auto status = outgoing_.AddProtocol<sample_i2ctemperature::Device>(this, Name());
- if (status.status_value() != ZX_OK) {
- FDF_SLOG(ERROR, "Failed to add protocol", KV("status", status.status_string()));
- return status;
- }
-
- status = SetupI2cChannel();
if (status.is_error()) {
+ FDF_SLOG(ERROR, "Failed to add protocol", KV("status", status.status_string()));
+ return status.take_error();
+ }
+ status = outgoing_.Serve(std::move(outgoing_dir));
+ if (status.is_error()) {
+ FDF_SLOG(ERROR, "Failed to serve outgoing directory", KV("status", status.status_string()));
return status.take_error();
}
- // Reset the sensor.
- auto result = i2c_channel_->Write16(kSoftResetCommand);
+ // Connect to the I2C bus controller.
+ auto result = SetupI2cChannel();
if (result.is_error()) {
- FDF_SLOG(ERROR, "Failed to send reset command: ", KV("status", result.status_string()));
+ return result.take_error();
}
+ // Reset the sensor.
+ auto write_result = i2c_channel_->Write16(kSoftResetCommand);
+ if (write_result.is_error()) {
+ FDF_SLOG(ERROR, "Failed to send reset command: ", KV("status", write_result.status_string()));
+ return write_result.take_error();
+ }
+
+ // Read the initial temperature value.
+ auto read_result = i2c_channel_->Read16();
+ if (read_result.is_error()) {
+ FDF_SLOG(ERROR, "Failed to read temperature: ", KV("status", read_result.status_string()));
+ return read_result.take_error();
+ }
+
+ uint32_t temperature = read_result.value();
+ FDF_SLOG(INFO, "I2C temperature: ", KV("temperature", temperature));
+
return zx::ok();
}
+// Connect to the `fuchsia.hardware.i2c/Device` protocol offered by the parent device node.
zx::status<> I2cTemperatureDriver::SetupI2cChannel() {
if (i2c_channel_) {
return zx::ok();
@@ -64,6 +81,7 @@
return zx::ok();
}
+// Protocol method in `sample.i2ctemperature` to return the current temperature
void I2cTemperatureDriver::ReadTemperature(ReadTemperatureRequestView request,
ReadTemperatureCompleter::Sync &completer) {
auto channel_status = SetupI2cChannel();
@@ -93,6 +111,7 @@
return completer.ReplySuccess(temp_value);
}
+// Protocol method in `sample.i2ctemperature` to reset the temperature senseor
void I2cTemperatureDriver::ResetSensor(ResetSensorRequestView request,
ResetSensorCompleter::Sync &completer) {
auto channel_status = SetupI2cChannel();
diff --git a/src/i2c_temperature/i2c_temperature.h b/src/i2c_temperature/driver/i2c_temperature.h
similarity index 94%
rename from src/i2c_temperature/i2c_temperature.h
rename to src/i2c_temperature/driver/i2c_temperature.h
index c6b9f73..af83d17 100644
--- a/src/i2c_temperature/i2c_temperature.h
+++ b/src/i2c_temperature/driver/i2c_temperature.h
@@ -18,7 +18,7 @@
namespace i2c_temperature {
-// Sample driver that demonstrates how to communicate through an I2C protocol.
+// Sample driver for a virtual temperature sensor device connected to an I2C bus controller.
class I2cTemperatureDriver : public fidl::WireServer<sample_i2ctemperature::Device> {
public:
I2cTemperatureDriver(async_dispatcher_t* dispatcher,
@@ -40,7 +40,7 @@
fidl::WireSharedClient<fuchsia_driver_framework::Node> node, driver::Namespace ns,
driver::Logger logger);
- // fuchsia.hardware.i2ctemperature/Device:
+ // sample.i2ctemperature/Device:
void ReadTemperature(ReadTemperatureRequestView request,
ReadTemperatureCompleter::Sync& completer);
void ResetSensor(ResetSensorRequestView request, ResetSensorCompleter::Sync& completer);
diff --git a/src/i2c_temperature/driver/meta/i2c_temperature.cml b/src/i2c_temperature/driver/meta/i2c_temperature.cml
new file mode 100644
index 0000000..1b87733
--- /dev/null
+++ b/src/i2c_temperature/driver/meta/i2c_temperature.cml
@@ -0,0 +1,28 @@
+// Copyright 2022 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+{
+ include: [
+ 'syslog/client.shard.cml',
+ ],
+ program: {
+ runner: 'driver',
+ binary: 'lib/libi2c_temperature.so',
+ bind: 'meta/bind/i2c_temperature.bindbc'
+ },
+ // Consume the I2C device capability from the parent
+ use: [
+ { protocol: 'fuchsia.hardware.i2c.Device' },
+ { service: 'fuchsia.driver.compat.Service' },
+ ],
+ // Provide the temperature device capability to other components
+ capabilities: [
+ { protocol: 'sample.i2ctemperature.Device' },
+ ],
+ expose: [
+ {
+ protocol: 'sample.i2ctemperature.Device',
+ from: 'self',
+ },
+ ],
+}
diff --git a/src/i2c_temperature/fidl/BUILD.bazel b/src/i2c_temperature/fidl/BUILD.bazel
new file mode 100644
index 0000000..8aa38fb
--- /dev/null
+++ b/src/i2c_temperature/fidl/BUILD.bazel
@@ -0,0 +1,31 @@
+# Copyright 2022 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+load(
+ "@rules_fuchsia//fuchsia:defs.bzl",
+ "fuchsia_fidl_library",
+ "fuchsia_fidl_llcpp_library",
+)
+
+fuchsia_fidl_library(
+ name = "sample.i2ctemperature",
+ srcs = [
+ "i2c_temperature.fidl",
+ ],
+ library = "sample.i2ctemperature",
+ visibility = ["//visibility:public"],
+ deps = [
+ "@fuchsia_sdk//fidl/zx:zx",
+ ],
+)
+
+fuchsia_fidl_llcpp_library(
+ name = "sample.i2ctemperature_cc",
+ library = ":sample.i2ctemperature",
+ visibility = ["//visibility:public"],
+ deps = [
+ "@fuchsia_sdk//fidl/zx:zx_llcpp_cc",
+ "@fuchsia_sdk//pkg/fidl_cpp_wire",
+ ],
+)
diff --git a/src/i2c_temperature/i2c_temperature.fidl b/src/i2c_temperature/fidl/i2c_temperature.fidl
similarity index 100%
rename from src/i2c_temperature/i2c_temperature.fidl
rename to src/i2c_temperature/fidl/i2c_temperature.fidl
diff --git a/src/i2c_temperature/i2c_temperature.bind b/src/i2c_temperature/i2c_temperature.bind
deleted file mode 100644
index bbf5f17..0000000
--- a/src/i2c_temperature/i2c_temperature.bind
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2022 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-using fuchsia.i2c;
-
-fuchsia.BIND_PROTOCOL == fuchsia.i2c.BIND_PROTOCOL.DEVICE;
-fuchsia.BIND_I2C_ADDRESS == 0xFF;
\ No newline at end of file
diff --git a/src/i2c_temperature/lib/BUILD.bazel b/src/i2c_temperature/lib/BUILD.bazel
new file mode 100644
index 0000000..671b8c9
--- /dev/null
+++ b/src/i2c_temperature/lib/BUILD.bazel
@@ -0,0 +1,10 @@
+# Copyright 2022 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+cc_library(
+ name = "lib",
+ hdrs = ["include/constants.h"],
+ includes = ["include"],
+ visibility = ["//visibility:public"],
+)
diff --git a/src/i2c_temperature/constants.h b/src/i2c_temperature/lib/include/constants.h
similarity index 100%
rename from src/i2c_temperature/constants.h
rename to src/i2c_temperature/lib/include/constants.h
diff --git a/src/i2c_temperature/meta/i2c_temperature.cml b/src/i2c_temperature/meta/i2c_temperature.cml
deleted file mode 100644
index 42cb06a..0000000
--- a/src/i2c_temperature/meta/i2c_temperature.cml
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- program: {
- runner: 'driver',
- binary: 'lib/libi2c_temperature.so',
- bind: 'meta/bind/i2c_temperature.bindbc'
- },
- use: [
- {
- protocol: [
- 'fuchsia.logger.LogSink',
- 'fuchsia.hardware.i2c.Device',
- ],
- },
- { service: "fuchsia.driver.compat.Service" },
- ],
-}
diff --git a/src/i2c_temperature/meta/test_i2c_controller.cml b/src/i2c_temperature/meta/test_i2c_controller.cml
deleted file mode 100644
index 314bc14..0000000
--- a/src/i2c_temperature/meta/test_i2c_controller.cml
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- program: {
- runner: 'driver',
- binary: 'lib/libtest_controller.so',
- bind: 'meta/bind/test_controller.bindbc'
- },
- use: [
- {
- protocol: [
- 'fuchsia.logger.LogSink',
- ],
- },
- { service: "fuchsia.driver.compat.Service" },
- ],
- capabilities: [
- { protocol: 'fuchsia.hardware.i2c.Device' },
- ],
- expose: [
- {
- protocol: 'fuchsia.hardware.i2c.Device',
- from: 'self',
- },
- ],
-}
diff --git a/src/i2c_temperature/test_i2c_controller.cc b/src/i2c_temperature/test_i2c_controller.cc
deleted file mode 100644
index 3396fc9..0000000
--- a/src/i2c_temperature/test_i2c_controller.cc
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright 2022 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/i2c_temperature/test_i2c_controller.h"
-
-#include <endian.h>
-#include <fidl/fuchsia.component.decl/cpp/wire.h>
-#include <lib/driver2/record_cpp.h>
-
-#include "src/i2c_temperature/constants.h"
-
-namespace fdf {
-using namespace fuchsia_driver_framework;
-} // namespace fdf
-
-namespace test_i2c_controller {
-
-namespace fcd = fuchsia_component_decl;
-
-namespace {
-
-constexpr uint32_t kStartingTemp = 20;
-constexpr uint32_t kTempIncrement = 5;
-
-} // namespace
-
-zx::status<std::unique_ptr<TestI2cController>> TestI2cController::Start(
- fdf::wire::DriverStartArgs& start_args, fdf::UnownedDispatcher dispatcher,
- fidl::WireSharedClient<fdf::Node> node, driver::Namespace ns, driver::Logger logger) {
- auto driver = std::make_unique<TestI2cController>(dispatcher->async_dispatcher(), std::move(node),
- std::move(ns), std::move(logger));
- auto result = driver->Run(std::move(start_args.outgoing_dir()));
- if (result.is_error()) {
- return result.take_error();
- }
-
- return zx::ok(std::move(driver));
-}
-
-zx::status<> TestI2cController::Run(fidl::ServerEnd<fuchsia_io::Directory> outgoing_dir) {
- temperature_ = kStartingTemp;
-
- auto service = [this](fidl::ServerEnd<fuchsia_hardware_i2c::Device> server_end) {
- fidl::BindServer(dispatcher_, std::move(server_end), this);
- };
-
- auto status = outgoing_.AddProtocol<fuchsia_hardware_i2c::Device>(std::move(service));
- if (status.status_value() != ZX_OK) {
- FDF_SLOG(ERROR, "Failed to add protocol", KV("status", status.status_string()));
- return status;
- }
-
- status = AddChild();
- if (status.status_value() != ZX_OK) {
- return status;
- }
-
- return outgoing_.Serve(std::move(outgoing_dir));
-}
-
-zx::status<> TestI2cController::AddChild() {
- fidl::Arena arena;
-
- // Offer `fuchsia.hardware.i2c.Device` to the driver that binds to the node.
- auto protocol_offer =
- fcd::wire::OfferProtocol::Builder(arena)
- .source_name(arena, fidl::DiscoverableProtocolName<fuchsia_hardware_i2c::Device>)
- .target_name(arena, fidl::DiscoverableProtocolName<fuchsia_hardware_i2c::Device>)
- .dependency_type(fcd::wire::DependencyType::kStrong)
- .Build();
- fcd::wire::Offer offer = fcd::wire::Offer::WithProtocol(arena, protocol_offer);
-
- // Set the properties of the node that a driver will bind to.
- // TODO(fxb/98831): Replace this once bind library protocol definitions are available.
- auto properties = fidl::VectorView<fdf::wire::NodeProperty>(arena, 2);
- properties[0] = fdf::wire::NodeProperty::Builder(arena)
- .key(fdf::wire::NodePropertyKey::WithIntValue(1 /* BIND_PROTOCOL */))
- .value(fdf::wire::NodePropertyValue::WithIntValue(24))
- .Build();
- properties[1] = fdf::wire::NodeProperty::Builder(arena)
- .key(fdf::wire::NodePropertyKey::WithIntValue(0x0A02 /* BIND_I2C_ADDRESS */))
- .value(fdf::wire::NodePropertyValue::WithIntValue(0xff))
- .Build();
-
- auto args = fdf::wire::NodeAddArgs::Builder(arena)
- .name(arena, "i2c-child")
- .offers(fidl::VectorView<fcd::wire::Offer>::FromExternal(&offer, 1))
- .properties(properties)
- .Build();
-
- // Create endpoints of the `NodeController` for the node.
- auto endpoints = fidl::CreateEndpoints<fdf::NodeController>();
- if (endpoints.is_error()) {
- FDF_SLOG(ERROR, "Failed to create endpoint", KV("status", endpoints.status_string()));
- return zx::error(endpoints.status_value());
- }
-
- auto result = node_.sync()->AddChild(args, std::move(endpoints->server), {});
- if (!result.ok()) {
- FDF_SLOG(ERROR, "Failed to add child", KV("status", result.status_string()));
- return zx::error(result.status());
- }
-
- return zx::ok();
-}
-
-void TestI2cController::HandleWrite(const fidl::VectorView<uint8_t> write_data) {
- // For simplicity, assume that we'll only receive integer commands from
- // I2cTemperatureDriver.
- if (write_data.count() > 4) {
- return;
- }
-
- uint8_t bytes[4];
- for (uint32_t i = 0; i < write_data.count(); i++) {
- bytes[i] = write_data.at(i);
- }
-
- int value;
- std::memcpy(&value, bytes, sizeof(int));
- value = be16toh(value);
-
- if (value == i2c_temperature::kSoftResetCommand) {
- FDF_SLOG(INFO, "Reset command received");
- temperature_ = kStartingTemp;
- } else if (value == i2c_temperature::kStartMeasurementCommand) {
- FDF_SLOG(INFO, "Measurement command received");
- temperature_ += kTempIncrement;
- } else {
- FDF_SLOG(WARNING, "Received unknown command ", KV("command", value));
- }
-}
-
-void TestI2cController::Transfer(TransferRequestView request, TransferCompleter::Sync& completer) {
- FDF_SLOG(INFO, "Received transfer request");
-
- if (request->transactions.count() < 1) {
- completer.ReplyError(ZX_ERR_INVALID_ARGS);
- return;
- }
-
- // Create a vector of read transfers
- fidl::Arena allocator;
- std::vector<fidl::VectorView<uint8_t>> read_data;
-
- for (size_t i = 0; i < request->transactions.count(); ++i) {
- if (!request->transactions[i].has_data_transfer()) {
- completer.ReplyError(ZX_ERR_INVALID_ARGS);
- return;
- }
-
- const auto& transfer = request->transactions[i].data_transfer();
-
- // Handle write transaction.
- if (transfer.is_write_data()) {
- if (transfer.write_data().count() <= 0) {
- completer.ReplyError(ZX_ERR_INVALID_ARGS);
- return;
- }
-
- HandleWrite(transfer.write_data());
- continue;
- }
-
- // Handle read transaction.
- auto read_value = htobe16(temperature_);
- auto read_bytes = fidl::VectorView<uint8_t>(allocator, 4);
- for (size_t i = 0; i < 4; i++) {
- read_bytes[i] = read_value >> (i * 8) & 0xff;
- }
- read_data.push_back(read_bytes);
- }
-
- auto read_results = fidl::VectorView<fidl::VectorView<uint8_t>>(allocator, read_data.size());
- for (size_t i = 0; i < read_data.size(); i++) {
- read_results[i] = read_data[i];
- }
-
- completer.ReplySuccess(read_results);
-}
-
-} // namespace test_i2c_controller
-
-FUCHSIA_DRIVER_RECORD_CPP_V1(test_i2c_controller::TestI2cController);
diff --git a/src/i2c_temperature/test_i2c_controller.h b/src/i2c_temperature/test_i2c_controller.h
deleted file mode 100644
index 403fe81..0000000
--- a/src/i2c_temperature/test_i2c_controller.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2022 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef FUCHSIA_SDK_EXAMPLES_SRC_I2C_TEMPERATURE_TESTING_TEST_I2C_CONTROLLER_H_
-#define FUCHSIA_SDK_EXAMPLES_SRC_I2C_TEMPERATURE_TESTING_TEST_I2C_CONTROLLER_H_
-
-#include <fidl/fuchsia.driver.framework/cpp/wire.h>
-#include <fidl/fuchsia.hardware.i2c/cpp/wire.h>
-#include <lib/async/cpp/executor.h>
-#include <lib/driver2/namespace.h>
-#include <lib/driver2/structured_logger.h>
-#include <lib/fdf/cpp/dispatcher.h>
-#include <lib/sys/component/llcpp/outgoing_directory.h>
-
-namespace test_i2c_controller {
-
-// Test driver that interacts with the i2c temperature driver. It implements the I2c protocol
-// and emulates a behavior where it receives commands for a temperature and returns a fake
-// temperature. The temperature it returns increase by 5 each time it receives a measurement
-// command. When it receives a reset command, the temperature is reset back to the starting
-// value.
-class TestI2cController : public fidl::WireServer<fuchsia_hardware_i2c::Device> {
- public:
- TestI2cController(async_dispatcher_t* dispatcher,
- fidl::WireSharedClient<fuchsia_driver_framework::Node> node,
- driver::Namespace ns, driver::Logger logger)
- : dispatcher_(dispatcher),
- outgoing_(component::OutgoingDirectory::Create(dispatcher)),
- ns_(std::move(ns)),
- logger_(std::move(logger)),
- node_(std::move(node)) {}
-
- virtual ~TestI2cController() = default;
-
- static constexpr const char* Name() { return "test-i2c-controller"; }
-
- static zx::status<std::unique_ptr<TestI2cController>> Start(
- fuchsia_driver_framework::wire::DriverStartArgs& start_args,
- fdf::UnownedDispatcher dispatcher,
- fidl::WireSharedClient<fuchsia_driver_framework::Node> node, driver::Namespace ns,
- driver::Logger logger);
-
- void Transfer(TransferRequestView request, TransferCompleter::Sync& completer);
-
- private:
- zx::status<> Run(fidl::ServerEnd<fuchsia_io::Directory> outgoing_dir);
- zx::status<> AddChild();
-
- void HandleWrite(const fidl::VectorView<uint8_t> write_data);
-
- uint32_t temperature_;
-
- async_dispatcher_t* const dispatcher_;
-
- component::OutgoingDirectory outgoing_;
- driver::Namespace ns_;
- driver::Logger logger_;
-
- fidl::WireSharedClient<fuchsia_driver_framework::Node> node_;
- fidl::WireSharedClient<fuchsia_driver_framework::NodeController> controller_;
-};
-
-} // namespace test_i2c_controller
-
-#endif // FUCHSIA_SDK_EXAMPLES_SRC_I2C_TEMPERATURE_TESTING_TEST_I2C_CONTROLLER_H_