From dcf5d949dc58204ecc989f8a42e636985437f373 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Thu, 2 May 2024 13:53:31 +1000 Subject: [PATCH] Initial support for the Rust Embedded embedded-hal This is very initial support for the embedded_hal [1]. This allows general embedded Rust crates to be built on top of libtock-rs with minimal porting effort. This currently just stubs out the support and implements the `digital::OutputPin` trait for GPIO pins. 1: https://docs.rs/embedded-hal/1.0.0/embedded_hal/index.html Signed-off-by: Alistair Francis --- Cargo.toml | 9 +++++++++ README.md | 13 +++++++++++++ apis/gpio/Cargo.toml | 4 ++++ apis/gpio/src/lib.rs | 16 ++++++++++++++++ platform/Cargo.toml | 6 ++++++ platform/src/error_code.rs | 8 ++++++++ 6 files changed, 56 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 584a5581..76e7a1c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,13 @@ version = "0.1.0" # more information. rust-version = "1.74" +[features] +rust_embedded = [ + "embedded-hal", + "libtock_platform/rust_embedded", + "libtock_gpio/rust_embedded" +] + [dependencies] libtock_adc = { path = "apis/adc" } libtock_air_quality = { path = "apis/air_quality" } @@ -38,6 +45,8 @@ libtock_runtime = { path = "runtime" } libtock_sound_pressure = { path = "apis/sound_pressure" } libtock_temperature = { path = "apis/temperature" } +embedded-hal = { version = "1.0", optional = true } + [build-dependencies] libtock_build_scripts = { path = "build_scripts" } diff --git a/README.md b/README.md index 84b37485..7b68be0a 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,19 @@ This script does the following steps for you: - create a TAB (tock application bundle) - if you have a J-Link compatible board connected: flash this TAB to your board (using tockloader) +### Enabling rust-embedded support + +libtock-rs can be built to be compatible with the rust-embedded +[embedded_hal](https://docs.rs/embedded-hal/1.0.0/embedded_hal/index.html) by +including the following when running `make` + +```shell +FEATURES=rust_embedded +``` + +If using libtock-rs or a sub-crate as a cargo dependency the `rust_embedded` +can also be enabled via Cargo. + ### Building a generic TAB (Tock Application Bundle) file To build your example for a variety of boards you can use diff --git a/apis/gpio/Cargo.toml b/apis/gpio/Cargo.toml index 16ddeb2c..d32da173 100644 --- a/apis/gpio/Cargo.toml +++ b/apis/gpio/Cargo.toml @@ -8,8 +8,12 @@ repository = "https://www.github.com/tock/libtock-rs" rust-version.workspace = true description = "libtock gpio driver" +[features] +rust_embedded = ["embedded-hal"] + [dependencies] libtock_platform = { path = "../../platform" } +embedded-hal = { version = "1.0", optional = true } [dev-dependencies] libtock_unittest = { path = "../../unittest" } diff --git a/apis/gpio/src/lib.rs b/apis/gpio/src/lib.rs index afdc41e8..ae8c3c43 100644 --- a/apis/gpio/src/lib.rs +++ b/apis/gpio/src/lib.rs @@ -231,6 +231,22 @@ impl Gpio { } } +#[cfg(feature = "rust_embedded")] +impl<'a, S: Syscalls> embedded_hal::digital::ErrorType for OutputPin<'a, S> { + type Error = ErrorCode; +} + +#[cfg(feature = "rust_embedded")] +impl<'a, S: Syscalls> embedded_hal::digital::OutputPin for OutputPin<'a, S> { + fn set_low(&mut self) -> Result<(), Self::Error> { + self.clear() + } + + fn set_high(&mut self) -> Result<(), Self::Error> { + self.set() + } +} + #[cfg(test)] mod tests; diff --git a/platform/Cargo.toml b/platform/Cargo.toml index c6cf5b89..5da05582 100644 --- a/platform/Cargo.toml +++ b/platform/Cargo.toml @@ -12,3 +12,9 @@ name = "libtock_platform" repository = "https://www.github.com/tock/libtock/rs" rust-version.workspace = true version = "0.1.0" + +[features] +rust_embedded = ["embedded-hal"] + +[dependencies] +embedded-hal = { version = "1.0", optional = true } diff --git a/platform/src/error_code.rs b/platform/src/error_code.rs index 5f85446c..42eca7c8 100644 --- a/platform/src/error_code.rs +++ b/platform/src/error_code.rs @@ -283,3 +283,11 @@ impl TryFrom for ErrorCode { } } } + +#[cfg(feature = "rust_embedded")] +impl embedded_hal::digital::Error for ErrorCode { + fn kind(&self) -> embedded_hal::digital::ErrorKind { + use embedded_hal::digital::ErrorKind; + ErrorKind::Other + } +}