From e6e6de435ecb1158003a73b0c6a079cfe350eab1 Mon Sep 17 00:00:00 2001 From: Adrian Ariton Date: Sun, 2 Apr 2023 15:24:17 +0300 Subject: [PATCH 1/2] Sound_pressure, proximity --- Cargo.toml | 2 + Makefile | 2 +- apis/proximity/Cargo.toml | 17 +++++++ apis/proximity/src/lib.rs | 58 +++++++++++++++++++++++ apis/proximity/src/tests.rs | 81 ++++++++++++++++++++++++++++++++ apis/sound_pressure/Cargo.toml | 17 +++++++ apis/sound_pressure/src/lib.rs | 54 +++++++++++++++++++++ apis/sound_pressure/src/tests.rs | 81 ++++++++++++++++++++++++++++++++ examples/proximity.rs | 40 ++++++++++++++++ examples/soundpressure.rs | 38 +++++++++++++++ runner/src/tockloader.rs | 2 +- runtime/layouts/microbit_v2.ld | 2 +- src/lib.rs | 10 ++++ 13 files changed, 401 insertions(+), 3 deletions(-) create mode 100644 apis/proximity/Cargo.toml create mode 100644 apis/proximity/src/lib.rs create mode 100644 apis/proximity/src/tests.rs create mode 100644 apis/sound_pressure/Cargo.toml create mode 100644 apis/sound_pressure/src/lib.rs create mode 100644 apis/sound_pressure/src/tests.rs create mode 100644 examples/proximity.rs create mode 100644 examples/soundpressure.rs diff --git a/Cargo.toml b/Cargo.toml index aefbca93..e67ef0fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,8 @@ libtock_console = { path = "apis/console" } libtock_debug_panic = { path = "panic_handlers/debug_panic" } libtock_gpio = { path = "apis/gpio" } libtock_leds = { path = "apis/leds" } +libtock_proximity = { path = "apis/proximity" } +libtock_sound_pressure = { path = "apis/sound_pressure" } libtock_low_level_debug = { path = "apis/low_level_debug" } libtock_platform = { path = "platform" } libtock_runtime = { path = "runtime" } diff --git a/Makefile b/Makefile index 08425a7e..b8b099ec 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,7 @@ release=--release endif .PHONY: setup -setup: setup-qemu +setup: #setup-qemu cargo install elf2tab cargo miri setup rustup target add --toolchain stable thumbv7em-none-eabi diff --git a/apis/proximity/Cargo.toml b/apis/proximity/Cargo.toml new file mode 100644 index 00000000..989c4722 --- /dev/null +++ b/apis/proximity/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "libtock_proximity" +version = "0.1.0" +authors = [ + "Tock Project Developers ", + "dcz ", +] +license = "MIT/Apache-2.0" +edition = "2018" +repository = "https://www.github.com/tock/libtock-rs" +description = "libtock alarm driver" + +[dependencies] +libtock_platform = { path = "../../platform" } + +[dev-dependencies] +libtock_unittest = { path = "../../unittest" } diff --git a/apis/proximity/src/lib.rs b/apis/proximity/src/lib.rs new file mode 100644 index 00000000..edb70708 --- /dev/null +++ b/apis/proximity/src/lib.rs @@ -0,0 +1,58 @@ +#![no_std] + +use core::cell::Cell; +use libtock_platform::{ + share, subscribe::OneId, DefaultConfig, ErrorCode, Subscribe, Syscalls, Upcall, +}; + +pub struct Proximity(S); + +impl Proximity { + /// Returns Ok() if the driver was present.This does not necessarily mean + /// that the driver is working. + pub fn exists() -> Result<(), ErrorCode> { + S::command(DRIVER_NUM, EXISTS, 0, 0).to_result() + } + + pub fn read_proximity() -> Result { + S::command(DRIVER_NUM, 1, 0, 0).to_result() + } + + pub fn read_proximity_on_interrupt() -> Result { + S::command(DRIVER_NUM, 2, 0, 0).to_result() + } + + /// Register an events listener + pub fn register_listener<'share, F: Fn(i32)>( + listener: &'share ProximityListener, + subscribe: share::Handle>, + ) -> Result<(), ErrorCode> { + S::subscribe::<_, _, DefaultConfig, DRIVER_NUM, 0>(subscribe, listener) + } + + /// Unregister the events listener + pub fn unregister_listener() { + S::unsubscribe(DRIVER_NUM, 0) + } +} + +pub struct ProximityListener(pub F); +impl Upcall> for ProximityListener { + fn upcall(&self, prox_val: u32, _arg1: u32, _arg2: u32) { + self.0(prox_val as i32) + } +} + +#[cfg(test)] +mod tests; + +// ----------------------------------------------------------------------------- +// Driver number and command IDs +// ----------------------------------------------------------------------------- + +const DRIVER_NUM: u32 = 0x60006; + +// Command IDs + +const EXISTS: u32 = 0; +const READ_TEMP: u32 = 1; \ No newline at end of file diff --git a/apis/proximity/src/tests.rs b/apis/proximity/src/tests.rs new file mode 100644 index 00000000..e3497fe7 --- /dev/null +++ b/apis/proximity/src/tests.rs @@ -0,0 +1,81 @@ +use core::cell::Cell; +use libtock_platform::{share, ErrorCode, Syscalls, YieldNoWaitReturn}; +use libtock_unittest::fake; + +type Temperature = super::Temperature; + +#[test] +fn no_driver() { + let _kernel = fake::Kernel::new(); + assert_eq!(Temperature::exists(), Err(ErrorCode::NoDevice)); +} + +#[test] +fn driver_check() { + let kernel = fake::Kernel::new(); + let driver = fake::Temperature::new(); + kernel.add_driver(&driver); + + assert_eq!(Temperature::exists(), Ok(())); +} + +#[test] +fn read_temperature() { + let kernel = fake::Kernel::new(); + let driver = fake::Temperature::new(); + kernel.add_driver(&driver); + + assert_eq!(Temperature::read_temperature(), Ok(())); + assert!(driver.is_busy()); + + assert_eq!(Temperature::read_temperature(), Err(ErrorCode::Busy)); + assert_eq!(Temperature::read_temperature_sync(), Err(ErrorCode::Busy)); +} + +#[test] +fn register_unregister_listener() { + let kernel = fake::Kernel::new(); + let driver = fake::Temperature::new(); + kernel.add_driver(&driver); + + let temperature_cell: Cell> = Cell::new(None); + let listener = crate::TemperatureListener(|temp_val| { + temperature_cell.set(Some(temp_val)); + }); + share::scope(|subscribe| { + assert_eq!(Temperature::read_temperature(), Ok(())); + driver.set_value(100); + assert_eq!(fake::Syscalls::yield_no_wait(), YieldNoWaitReturn::NoUpcall); + + assert_eq!(Temperature::register_listener(&listener, subscribe), Ok(())); + assert_eq!(Temperature::read_temperature(), Ok(())); + driver.set_value(100); + assert_eq!(fake::Syscalls::yield_no_wait(), YieldNoWaitReturn::Upcall); + assert_eq!(temperature_cell.get(), Some(100)); + + Temperature::unregister_listener(); + assert_eq!(Temperature::read_temperature(), Ok(())); + driver.set_value(100); + assert_eq!(fake::Syscalls::yield_no_wait(), YieldNoWaitReturn::NoUpcall); + }); +} + +#[test] +fn read_temperature_sync() { + let kernel = fake::Kernel::new(); + let driver = fake::Temperature::new(); + kernel.add_driver(&driver); + + driver.set_value_sync(1000); + assert_eq!(Temperature::read_temperature_sync(), Ok(1000)); +} + +#[test] +fn negative_value() { + let kernel = fake::Kernel::new(); + let driver = fake::Temperature::new(); + kernel.add_driver(&driver); + + driver.set_value_sync(-1000); + assert_eq!(Temperature::read_temperature_sync(), Ok(-1000)); +} \ No newline at end of file diff --git a/apis/sound_pressure/Cargo.toml b/apis/sound_pressure/Cargo.toml new file mode 100644 index 00000000..ff0b7242 --- /dev/null +++ b/apis/sound_pressure/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "libtock_sound_pressure" +version = "0.1.0" +authors = [ + "Tock Project Developers ", + "dcz ", +] +license = "MIT/Apache-2.0" +edition = "2018" +repository = "https://www.github.com/tock/libtock-rs" +description = "libtock alarm driver" + +[dependencies] +libtock_platform = { path = "../../platform" } + +[dev-dependencies] +libtock_unittest = { path = "../../unittest" } diff --git a/apis/sound_pressure/src/lib.rs b/apis/sound_pressure/src/lib.rs new file mode 100644 index 00000000..43013da5 --- /dev/null +++ b/apis/sound_pressure/src/lib.rs @@ -0,0 +1,54 @@ +#![no_std] + +use core::cell::Cell; +use libtock_platform::{ + share, subscribe::OneId, DefaultConfig, ErrorCode, Subscribe, Syscalls, Upcall, +}; + +pub struct SoundPressure(S); + +impl SoundPressure { + /// Returns Ok() if the driver was present.This does not necessarily mean + /// that the driver is working. + pub fn exists() -> Result<(), ErrorCode> { + S::command(DRIVER_NUM, EXISTS, 0, 0).to_result() + } + + pub fn read_sound_pressure() -> Result { + S::command(DRIVER_NUM, 1, 0, 0).to_result() + } + + /// Register an events listener + pub fn register_listener<'share, F: Fn(i32)>( + listener: &'share SoundPressureListener, + subscribe: share::Handle>, + ) -> Result<(), ErrorCode> { + S::subscribe::<_, _, DefaultConfig, DRIVER_NUM, 0>(subscribe, listener) + } + + /// Unregister the events listener + pub fn unregister_listener() { + S::unsubscribe(DRIVER_NUM, 0) + } +} + +pub struct SoundPressureListener(pub F); +impl Upcall> for SoundPressureListener { + fn upcall(&self, prox_val: u32, _arg1: u32, _arg2: u32) { + self.0(prox_val as i32) + } +} + +#[cfg(test)] +mod tests; + +// ----------------------------------------------------------------------------- +// Driver number and command IDs +// ----------------------------------------------------------------------------- + +const DRIVER_NUM: u32 = 0x60006; + +// Command IDs + +const EXISTS: u32 = 0; +const READ_TEMP: u32 = 1; \ No newline at end of file diff --git a/apis/sound_pressure/src/tests.rs b/apis/sound_pressure/src/tests.rs new file mode 100644 index 00000000..e3497fe7 --- /dev/null +++ b/apis/sound_pressure/src/tests.rs @@ -0,0 +1,81 @@ +use core::cell::Cell; +use libtock_platform::{share, ErrorCode, Syscalls, YieldNoWaitReturn}; +use libtock_unittest::fake; + +type Temperature = super::Temperature; + +#[test] +fn no_driver() { + let _kernel = fake::Kernel::new(); + assert_eq!(Temperature::exists(), Err(ErrorCode::NoDevice)); +} + +#[test] +fn driver_check() { + let kernel = fake::Kernel::new(); + let driver = fake::Temperature::new(); + kernel.add_driver(&driver); + + assert_eq!(Temperature::exists(), Ok(())); +} + +#[test] +fn read_temperature() { + let kernel = fake::Kernel::new(); + let driver = fake::Temperature::new(); + kernel.add_driver(&driver); + + assert_eq!(Temperature::read_temperature(), Ok(())); + assert!(driver.is_busy()); + + assert_eq!(Temperature::read_temperature(), Err(ErrorCode::Busy)); + assert_eq!(Temperature::read_temperature_sync(), Err(ErrorCode::Busy)); +} + +#[test] +fn register_unregister_listener() { + let kernel = fake::Kernel::new(); + let driver = fake::Temperature::new(); + kernel.add_driver(&driver); + + let temperature_cell: Cell> = Cell::new(None); + let listener = crate::TemperatureListener(|temp_val| { + temperature_cell.set(Some(temp_val)); + }); + share::scope(|subscribe| { + assert_eq!(Temperature::read_temperature(), Ok(())); + driver.set_value(100); + assert_eq!(fake::Syscalls::yield_no_wait(), YieldNoWaitReturn::NoUpcall); + + assert_eq!(Temperature::register_listener(&listener, subscribe), Ok(())); + assert_eq!(Temperature::read_temperature(), Ok(())); + driver.set_value(100); + assert_eq!(fake::Syscalls::yield_no_wait(), YieldNoWaitReturn::Upcall); + assert_eq!(temperature_cell.get(), Some(100)); + + Temperature::unregister_listener(); + assert_eq!(Temperature::read_temperature(), Ok(())); + driver.set_value(100); + assert_eq!(fake::Syscalls::yield_no_wait(), YieldNoWaitReturn::NoUpcall); + }); +} + +#[test] +fn read_temperature_sync() { + let kernel = fake::Kernel::new(); + let driver = fake::Temperature::new(); + kernel.add_driver(&driver); + + driver.set_value_sync(1000); + assert_eq!(Temperature::read_temperature_sync(), Ok(1000)); +} + +#[test] +fn negative_value() { + let kernel = fake::Kernel::new(); + let driver = fake::Temperature::new(); + kernel.add_driver(&driver); + + driver.set_value_sync(-1000); + assert_eq!(Temperature::read_temperature_sync(), Ok(-1000)); +} \ No newline at end of file diff --git a/examples/proximity.rs b/examples/proximity.rs new file mode 100644 index 00000000..4cc0b3b8 --- /dev/null +++ b/examples/proximity.rs @@ -0,0 +1,40 @@ + +#![no_main] +#![no_std] + +use core::fmt::Write; +use libtock::console::Console; + +use libtock::alarm::{Alarm, Milliseconds}; +use libtock::runtime::{set_main, stack_size}; +use libtock::proximity::Proximity; + +set_main! {main} +stack_size! {0x200} + +fn main() { + match Proximity::exists() { + Ok(()) => writeln!(Console::writer(), "proxi driver available").unwrap(), + Err(_) => { + writeln!(Console::writer(), "proxi driver unavailable").unwrap(); + return; + } + } + + loop { + match Proximity::read_proximity() { + Ok(temp_val) => writeln!( + Console::writer(), + "Temperature: {}{}.{}*C\n", + if temp_val > 0 { "" } else { "-" }, + (temp_val) / 100, + (temp_val) % 100 + ) + .unwrap(), + Err(_) => writeln!(Console::writer(), "error while reading proxi",).unwrap(), + + } + + Alarm::sleep_for(Milliseconds(2000)).unwrap(); + } +} \ No newline at end of file diff --git a/examples/soundpressure.rs b/examples/soundpressure.rs new file mode 100644 index 00000000..ab6b9371 --- /dev/null +++ b/examples/soundpressure.rs @@ -0,0 +1,38 @@ + +#![no_main] +#![no_std] + +use core::fmt::Write; +use libtock::console::Console; + +use libtock::alarm::{Alarm, Milliseconds}; +use libtock::runtime::{set_main, stack_size}; +use libtock::sound_pressure::SoundPressure; + +set_main! {main} +stack_size! {0x200} + +fn main() { + match SoundPressure::exists() { + Ok(()) => writeln!(Console::writer(), "proxi driver available").unwrap(), + Err(_) => { + writeln!(Console::writer(), "proxi driver unavailable").unwrap(); + return; + } + } + + loop { + match SoundPressure::read_sound_pressure() { + Ok(temp_val) => writeln!( + Console::writer(), + "Pressure: {}\n", + temp_val + ) + .unwrap(), + Err(a) => writeln!(Console::writer(), "error while reading proxi {:?}", a).unwrap(), + + } + + Alarm::sleep_for(Milliseconds(2000)).unwrap(); + } +} \ No newline at end of file diff --git a/runner/src/tockloader.rs b/runner/src/tockloader.rs index bc4fe829..c274bdfb 100644 --- a/runner/src/tockloader.rs +++ b/runner/src/tockloader.rs @@ -11,7 +11,7 @@ pub fn deploy(cli: &Cli, platform: String, tab_path: PathBuf) -> Child { let flags: &[_] = match platform.as_str() { "clue_nrf52840" => &[], "hail" => &[], - "microbit_v2" => &["--bundle-apps"], + "microbit_v2" => &[], "nrf52" | "nrf52840" => &[ "--jlink", "--arch", diff --git a/runtime/layouts/microbit_v2.ld b/runtime/layouts/microbit_v2.ld index 684810e2..ec337a76 100644 --- a/runtime/layouts/microbit_v2.ld +++ b/runtime/layouts/microbit_v2.ld @@ -2,7 +2,7 @@ MEMORY { FLASH (X) : ORIGIN = 0x00040000, LENGTH = 256K - RAM (W) : ORIGIN = 0x20004000, LENGTH = 112K + RAM (W) : ORIGIN = 0x20005000, LENGTH = 112K } TBF_HEADER_SIZE = 0x60; diff --git a/src/lib.rs b/src/lib.rs index c13b39db..f532c29b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,3 +44,13 @@ pub mod temperature { pub type Temperature = temperature::Temperature; pub use temperature::TemperatureListener; } + +pub mod proximity { + use libtock_proximity as proximity; + pub type Proximity = proximity::Proximity; +} + +pub mod sound_pressure { + use libtock_sound_pressure as sound_pressure; + pub type SoundPressure = sound_pressure::SoundPressure; +} \ No newline at end of file From 8b74a9f8e7cef1e59c46810741291cfc11ae8378 Mon Sep 17 00:00:00 2001 From: Adrian Ariton Date: Sun, 2 Apr 2023 15:57:02 +0300 Subject: [PATCH 2/2] SoundPressure --- Cargo.toml | 2 ++ apis/proximity/src/lib.rs | 2 +- apis/sound_pressure/src/lib.rs | 37 +++++++++++++++++++++++++++++----- examples/proximity.rs | 6 ++---- examples/soundpressure.rs | 2 +- 5 files changed, 38 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e67ef0fc..07812f01 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,4 +52,6 @@ members = [ "tools/print_sizes", "ufmt", "unittest", + "apis/sound_pressure", + "apis/proximity" ] diff --git a/apis/proximity/src/lib.rs b/apis/proximity/src/lib.rs index edb70708..c9ab4c8b 100644 --- a/apis/proximity/src/lib.rs +++ b/apis/proximity/src/lib.rs @@ -50,7 +50,7 @@ mod tests; // Driver number and command IDs // ----------------------------------------------------------------------------- -const DRIVER_NUM: u32 = 0x60006; +const DRIVER_NUM: u32 = 0x60005; // Command IDs diff --git a/apis/sound_pressure/src/lib.rs b/apis/sound_pressure/src/lib.rs index 43013da5..d81abc93 100644 --- a/apis/sound_pressure/src/lib.rs +++ b/apis/sound_pressure/src/lib.rs @@ -14,8 +14,11 @@ impl SoundPressure { S::command(DRIVER_NUM, EXISTS, 0, 0).to_result() } - pub fn read_sound_pressure() -> Result { - S::command(DRIVER_NUM, 1, 0, 0).to_result() + /// Initiate a SoundPressure measurement. + /// + /// This function is used both for synchronous and asynchronous readings + pub fn read_sound_pressure() -> Result<(), ErrorCode> { + S::command(DRIVER_NUM, READ_TEMP, 0, 0).to_result() } /// Register an events listener @@ -30,12 +33,36 @@ impl SoundPressure { pub fn unregister_listener() { S::unsubscribe(DRIVER_NUM, 0) } + + /// Initiate a synchronous SoundPressure measurement. + /// Returns Ok(SoundPressure_value) if the operation was successful + /// SoundPressure_value is returned in hundreds of centigrades + pub fn read_sound_pressure_sync() -> Result { + let SoundPressure_cell: Cell> = Cell::new(None); + let listener = SoundPressureListener(|temp_val| { + SoundPressure_cell.set(Some(temp_val)); + }); + share::scope(|subscribe| { + if let Ok(()) = Self::register_listener(&listener, subscribe) { + if let Ok(()) = Self::read_sound_pressure() { + while SoundPressure_cell.get() == None { + S::yield_wait(); + } + } + } + }); + + match SoundPressure_cell.get() { + None => Err(ErrorCode::Busy), + Some(temp_val) => Ok(temp_val), + } + } } pub struct SoundPressureListener(pub F); impl Upcall> for SoundPressureListener { - fn upcall(&self, prox_val: u32, _arg1: u32, _arg2: u32) { - self.0(prox_val as i32) + fn upcall(&self, temp_val: u32, _arg1: u32, _arg2: u32) { + self.0(temp_val as i32) } } @@ -51,4 +78,4 @@ const DRIVER_NUM: u32 = 0x60006; // Command IDs const EXISTS: u32 = 0; -const READ_TEMP: u32 = 1; \ No newline at end of file +const READ_TEMP: u32 = 1; diff --git a/examples/proximity.rs b/examples/proximity.rs index 4cc0b3b8..137b5f8c 100644 --- a/examples/proximity.rs +++ b/examples/proximity.rs @@ -25,10 +25,8 @@ fn main() { match Proximity::read_proximity() { Ok(temp_val) => writeln!( Console::writer(), - "Temperature: {}{}.{}*C\n", - if temp_val > 0 { "" } else { "-" }, - (temp_val) / 100, - (temp_val) % 100 + "Proxi: {}\n", + (temp_val), ) .unwrap(), Err(_) => writeln!(Console::writer(), "error while reading proxi",).unwrap(), diff --git a/examples/soundpressure.rs b/examples/soundpressure.rs index ab6b9371..858b65d0 100644 --- a/examples/soundpressure.rs +++ b/examples/soundpressure.rs @@ -22,7 +22,7 @@ fn main() { } loop { - match SoundPressure::read_sound_pressure() { + match SoundPressure::read_sound_pressure_sync() { Ok(temp_val) => writeln!( Console::writer(), "Pressure: {}\n",