-
Notifications
You must be signed in to change notification settings - Fork 9
Sound pressure api and [in progress]Proximity api #24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| [package] | ||
| name = "libtock_proximity" | ||
| version = "0.1.0" | ||
| authors = [ | ||
| "Tock Project Developers <[email protected]>", | ||
| "dcz <[email protected]>", | ||
| ] | ||
| 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" } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -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: Syscalls>(S); | ||||||
|
|
||||||
| impl<S: Syscalls> Proximity<S> { | ||||||
| /// 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<u32, ErrorCode> { | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a comment explaining how this function works. |
||||||
| S::command(DRIVER_NUM, 1, 0, 0).to_result() | ||||||
| } | ||||||
|
|
||||||
| pub fn read_proximity_on_interrupt() -> Result<u32, ErrorCode> { | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a comment explaining how this function works. |
||||||
| S::command(DRIVER_NUM, 2, 0, 0).to_result() | ||||||
| } | ||||||
|
|
||||||
| /// Register an events listener | ||||||
| pub fn register_listener<'share, F: Fn(i32)>( | ||||||
| listener: &'share ProximityListener<F>, | ||||||
| subscribe: share::Handle<Subscribe<'share, S, DRIVER_NUM, 0>>, | ||||||
| ) -> 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<F: Fn(i32)>(pub F); | ||||||
| impl<F: Fn(i32)> Upcall<OneId<DRIVER_NUM, 0>> for ProximityListener<F> { | ||||||
| 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 = 0x60005; | ||||||
|
|
||||||
| // Command IDs | ||||||
|
|
||||||
| const EXISTS: u32 = 0; | ||||||
| const READ_TEMP: u32 = 1; | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a newline |
||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These tests are for the temperature. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| use core::cell::Cell; | ||
| use libtock_platform::{share, ErrorCode, Syscalls, YieldNoWaitReturn}; | ||
| use libtock_unittest::fake; | ||
|
|
||
| type Temperature = super::Temperature<fake::Syscalls>; | ||
|
|
||
| #[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<Option<i32>> = 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)); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| [package] | ||
| name = "libtock_sound_pressure" | ||
| version = "0.1.0" | ||
| authors = [ | ||
| "Tock Project Developers <[email protected]>", | ||
| "dcz <[email protected]>", | ||
| ] | ||
| 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" } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| #![no_std] | ||
|
|
||
| use core::cell::Cell; | ||
| use libtock_platform::{ | ||
| share, subscribe::OneId, DefaultConfig, ErrorCode, Subscribe, Syscalls, Upcall, | ||
| }; | ||
|
|
||
| pub struct SoundPressure<S: Syscalls>(S); | ||
|
|
||
| impl<S: Syscalls> SoundPressure<S> { | ||
| /// 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() | ||
| } | ||
|
|
||
| /// 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 | ||
| pub fn register_listener<'share, F: Fn(i32)>( | ||
| listener: &'share SoundPressureListener<F>, | ||
| subscribe: share::Handle<Subscribe<'share, S, DRIVER_NUM, 0>>, | ||
| ) -> Result<(), ErrorCode> { | ||
| S::subscribe::<_, _, DefaultConfig, DRIVER_NUM, 0>(subscribe, listener) | ||
| } | ||
|
|
||
| /// Unregister the events listener | ||
| 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<i32, ErrorCode> { | ||
| let SoundPressure_cell: Cell<Option<i32>> = 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<F: Fn(i32)>(pub F); | ||
| impl<F: Fn(i32)> Upcall<OneId<DRIVER_NUM, 0>> for SoundPressureListener<F> { | ||
| fn upcall(&self, temp_val: u32, _arg1: u32, _arg2: u32) { | ||
| self.0(temp_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; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| use core::cell::Cell; | ||
| use libtock_platform::{share, ErrorCode, Syscalls, YieldNoWaitReturn}; | ||
| use libtock_unittest::fake; | ||
|
|
||
| type Temperature = super::Temperature<fake::Syscalls>; | ||
|
|
||
| #[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<Option<i32>> = 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)); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert this.