Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand Down Expand Up @@ -50,4 +52,6 @@ members = [
"tools/print_sizes",
"ufmt",
"unittest",
"apis/sound_pressure",
"apis/proximity"
]
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ release=--release
endif

.PHONY: setup
setup: setup-qemu
setup: #setup-qemu

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please revert this.

cargo install elf2tab
cargo miri setup
rustup target add --toolchain stable thumbv7em-none-eabi
Expand Down
17 changes: 17 additions & 0 deletions apis/proximity/Cargo.toml
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" }
58 changes: 58 additions & 0 deletions apis/proximity/src/lib.rs
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> {

Choose a reason for hiding this comment

The 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> {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub fn read_proximity_on_interrupt() -> Result<u32, ErrorCode> {
pub fn enable_interrupt() -> Result<u32, ErrorCode> {

Choose a reason for hiding this comment

The 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;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a newline

81 changes: 81 additions & 0 deletions apis/proximity/src/tests.rs

Choose a reason for hiding this comment

The 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));
}
17 changes: 17 additions & 0 deletions apis/sound_pressure/Cargo.toml
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" }
81 changes: 81 additions & 0 deletions apis/sound_pressure/src/lib.rs
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;
81 changes: 81 additions & 0 deletions apis/sound_pressure/src/tests.rs
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));
}
Loading