lib/rpc: rp2040 reboot and temp RPCs
Change-Id: I4cddbc71ed22fc0d84f6d98822346c7857cb40b1
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/kudzu/+/193730
Reviewed-by: Armando Montanez <amontanez@google.com>
Commit-Queue: Anthony DiGirolamo <tonymd@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index d4b13b5..a8168db 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -69,7 +69,7 @@
# single super Python package for installation into the bootstrapped virtual
# environment.
pw_python_distribution("kudzu_python_distribution") {
- packages = _pigweed_python_packages
+ packages = _all_python_packages
generate_setup_cfg = {
name = "kudzu-dist"
version = "0.0.1"
diff --git a/README.md b/README.md
index 3eac59e..945efbd 100644
--- a/README.md
+++ b/README.md
@@ -126,12 +126,11 @@
### Host
-Run the host app and connect to it via `pw-system-console`:
+Run the host app and connect to it via `pw console`:
```sh
./out/gn/host_device_simulator.speed_optimized/obj/applications/badge/bin/badge & \
- pw-system-console --socket-addr default \
- --proto-globs third_party/pigweed/pw_rpc/echo.proto ; \
+ pw console --socket-addr default ; \
killall badge
```
@@ -145,12 +144,18 @@
picotool load -x $ELF
```
-Connect with `pw-system-console`:
+Connect with `pw console`:
```sh
-pw-system-console --verbose \
+pw console --verbose \
--baudrate 115200 \
- --proto-globs third_party/pigweed/pw_rpc/echo.proto \
--token-databases ./out/gn/rp2040.size_optimized/obj/applications/badge/bin/badge.elf \
--device /dev/rp2040
```
+
+From Python Repl window you can issue RPCs interactively:
+
+```
+>>> device.rpcs.kudzu.rpc.Kudzu.PackageTemp()
+(Status.OK, kudzu.rpc.PackageTempResponse(temp=27.60657501220703))
+```
diff --git a/applications/app_common_impl/BUILD.gn b/applications/app_common_impl/BUILD.gn
index ab29dba..242b24d 100644
--- a/applications/app_common_impl/BUILD.gn
+++ b/applications/app_common_impl/BUILD.gn
@@ -61,6 +61,7 @@
_pico_common_deps = [
"$PICO_ROOT/src/common/pico_base",
"$PICO_ROOT/src/common/pico_stdlib",
+ "$PICO_ROOT/src/rp2_common/hardware_adc",
"$PICO_ROOT/src/rp2_common/hardware_pwm",
"$PICO_ROOT/src/rp2_common/hardware_spi",
"$PICO_ROOT/src/rp2_common/hardware_vreg",
diff --git a/applications/app_common_impl/common_pico.cc b/applications/app_common_impl/common_pico.cc
index c3d6cf1..d94b060 100644
--- a/applications/app_common_impl/common_pico.cc
+++ b/applications/app_common_impl/common_pico.cc
@@ -20,6 +20,7 @@
#include "FreeRTOS.h"
#include "ft6236/device.h"
+#include "hardware/adc.h"
#include "hardware/gpio.h"
#include "hardware/pwm.h"
#include "hardware/vreg.h"
@@ -305,6 +306,8 @@
set_sys_clock_khz(250000, false);
#endif
+ adc_init();
+
ConfigStatusRgb();
// Set to a dim pink.
SetStatusRgb(32, 12, 32);
diff --git a/lib/rpc/BUILD.gn b/lib/rpc/BUILD.gn
new file mode 100644
index 0000000..4d3ad21
--- /dev/null
+++ b/lib/rpc/BUILD.gn
@@ -0,0 +1,40 @@
+# Copyright 2024 The Pigweed Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy of
+# the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+
+import("//build_overrides/pi_pico.gni")
+import("//build_overrides/pigweed.gni")
+
+import("$dir_pw_protobuf_compiler/proto.gni")
+
+config("public") {
+ include_dirs = [ "public" ]
+ visibility = [ ":*" ]
+}
+
+pw_proto_library("protos") {
+ sources = [ "kudzu.proto" ]
+ inputs = [ "kudzu.options" ]
+ deps = [ "$dir_pw_protobuf:common_protos" ]
+ prefix = "kudzu"
+}
+
+pw_source_set("kudzu_service") {
+ public_configs = [ ":public" ]
+ public_deps = [
+ ":protos.pwpb_rpc",
+ "$PICO_ROOT/src/rp2_common/hardware_adc",
+ "$PICO_ROOT/src/rp2_common/pico_bootrom",
+ ]
+ sources = [ "public/kudzu/kudzu_service_pwpb.h" ]
+}
diff --git a/lib/rpc/kudzu.options b/lib/rpc/kudzu.options
new file mode 100644
index 0000000..02cd8c4
--- /dev/null
+++ b/lib/rpc/kudzu.options
@@ -0,0 +1,13 @@
+// Copyright 2024 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
diff --git a/lib/rpc/kudzu.proto b/lib/rpc/kudzu.proto
new file mode 100644
index 0000000..0e06513
--- /dev/null
+++ b/lib/rpc/kudzu.proto
@@ -0,0 +1,43 @@
+// Copyright 2024 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+syntax = "proto3";
+
+package kudzu.rpc;
+
+import "pw_protobuf_protos/common.proto";
+
+service Kudzu {
+ rpc Reboot(RebootRequest) returns (RebootResponse);
+ rpc PackageTemp(PackageTempRequest) returns (PackageTempResponse);
+}
+
+message RebootType {
+ enum Enum {
+ UKNOWN = 0;
+ BOTH_MASS_STORAGE_AND_PICOBOOT = 1;
+ PICOBOOT_ONLY = 2;
+ MASS_STORAGE_ONLY = 3;
+ };
+}
+
+message RebootRequest {
+ RebootType.Enum reboot_type = 1; // Required
+}
+
+message RebootResponse {}
+
+message PackageTempRequest {}
+message PackageTempResponse {
+ float temp = 1;
+}
diff --git a/lib/rpc/public/kudzu/kudzu_service_pwpb.h b/lib/rpc/public/kudzu/kudzu_service_pwpb.h
new file mode 100644
index 0000000..9bf7e54
--- /dev/null
+++ b/lib/rpc/public/kudzu/kudzu_service_pwpb.h
@@ -0,0 +1,61 @@
+// Copyright 2024 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+#pragma once
+
+#include "hardware/adc.h"
+#include "kudzu/kudzu.pwpb.h"
+#include "kudzu/kudzu.rpc.pwpb.h"
+#include "pico/bootrom.h"
+#include "pw_status/status.h"
+
+namespace kudzu::rpc {
+
+class KudzuService final : public pw_rpc::pwpb::Kudzu::Service<KudzuService> {
+ public:
+ pw::Status Reboot(const pwpb::RebootRequest::Message& request,
+ pwpb::RebootResponse::Message& /*response*/) {
+ uint32_t disable_interface_mask = 0;
+
+ if (request.reboot_type ==
+ pwpb::RebootType::Enum::BOTH_MASS_STORAGE_AND_PICOBOOT) {
+ disable_interface_mask = 0;
+ } else if (request.reboot_type == pwpb::RebootType::Enum::PICOBOOT_ONLY) {
+ disable_interface_mask = 1;
+ } else if (request.reboot_type ==
+ pwpb::RebootType::Enum::MASS_STORAGE_ONLY) {
+ disable_interface_mask = 2;
+ } else {
+ return pw::Status::Unknown();
+ }
+
+ reset_usb_boot(0, disable_interface_mask);
+ return pw::OkStatus();
+ }
+
+ pw::Status PackageTemp(const pwpb::PackageTempRequest::Message& /*request*/,
+ pwpb::PackageTempResponse::Message& response) {
+ adc_set_temp_sensor_enabled(true);
+ adc_select_input(4); // 4 is the on board temp sensor.
+
+ // See raspberry-pi-pico-c-sdk.pdf, Section '4.1.1. hardware_adc'
+ const float conversion_factor = 3.3f / (1 << 12);
+ float adc = static_cast<float>(adc_read()) * conversion_factor;
+ float temp_c = 27.0f - (adc - 0.706f) / 0.001721f;
+ response.temp = temp_c;
+
+ return pw::OkStatus();
+ }
+};
+
+} // namespace kudzu::rpc
diff --git a/pigweed.json b/pigweed.json
index 400d886..c5291a2 100644
--- a/pigweed.json
+++ b/pigweed.json
@@ -23,7 +23,7 @@
"function": "main"
},
"console": {
- "module": "pw_system.console",
+ "module": "kudzu_tools.console",
"function": "main"
},
"package": {
diff --git a/targets/rp2040/BUILD.gn b/targets/rp2040/BUILD.gn
index 6c7d9e7..ae3ba35 100644
--- a/targets/rp2040/BUILD.gn
+++ b/targets/rp2040/BUILD.gn
@@ -36,6 +36,7 @@
"$dir_pw_string",
"$dir_pw_system",
"$dir_pw_third_party/freertos",
+ "//lib/rpc:kudzu_service",
]
sources = [ "boot.cc" ]
}
diff --git a/targets/rp2040/boot.cc b/targets/rp2040/boot.cc
index 5ca25c8..788ec32 100644
--- a/targets/rp2040/boot.cc
+++ b/targets/rp2040/boot.cc
@@ -14,9 +14,12 @@
#include <array>
+#include "pw_system/rpc_server.h"
+
#define PW_LOG_MODULE_NAME "pw_system"
#include "FreeRTOS.h"
+#include "kudzu/kudzu_service_pwpb.h"
#include "pico/stdlib.h"
#include "pw_log/log.h"
#include "pw_string/util.h"
@@ -66,6 +69,8 @@
*pulIdleTaskStackSize = freertos_idle_stack.size();
}
+kudzu::rpc::KudzuService kudzu_service;
+
int main() {
// PICO_SDK Inits
stdio_init_all();
@@ -74,6 +79,7 @@
PW_LOG_INFO("pw_system main");
pw::system::Init();
+ pw::system::GetRpcServer().RegisterService(kudzu_service);
vTaskStartScheduler();
PW_UNREACHABLE;
}
diff --git a/tools/BUILD.gn b/tools/BUILD.gn
index ab199a1..af1fe2a 100644
--- a/tools/BUILD.gn
+++ b/tools/BUILD.gn
@@ -24,12 +24,19 @@
sources = [
"kudzu_tools/__init__.py",
"kudzu_tools/build_project.py",
+ "kudzu_tools/console.py",
"kudzu_tools/presubmit_checks.py",
]
python_deps = [
"$dir_pw_build/py",
"$dir_pw_cli/py",
"$dir_pw_presubmit/py",
+ "$dir_pw_protobuf:common_protos.python",
+ "$dir_pw_rpc:protos.python",
+ "$dir_pw_system/py",
+
+ # RPC protos to include for console interaction.
+ "//lib/rpc:protos.python",
]
pylintrc = "$dir_pigweed/.pylintrc"
}
diff --git a/tools/kudzu_tools/console.py b/tools/kudzu_tools/console.py
new file mode 100644
index 0000000..f184b6e
--- /dev/null
+++ b/tools/kudzu_tools/console.py
@@ -0,0 +1,36 @@
+# Copyright 2024 The Pigweed Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy of
+# the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+"""Wraps pw_system's console to inject additional RPC protos."""
+
+import argparse
+import sys
+from typing import Optional
+
+from pw_protobuf_protos import common_pb2
+import pw_system.console
+from kudzu import kudzu_pb2
+from pw_rpc import echo_pb2
+
+
+def main(args: Optional[argparse.Namespace] = None) -> int:
+ compiled_protos = [
+ common_pb2,
+ echo_pb2,
+ kudzu_pb2,
+ ]
+ return pw_system.console.main_with_compiled_protos(compiled_protos, args)
+
+
+if __name__ == '__main__':
+ sys.exit(main())