Skip to content

Commit

Permalink
Update third_party/libtock-drivers to support OpenSK.
Browse files Browse the repository at this point in the history
  • Loading branch information
gendx committed Aug 7, 2020
1 parent 5f1fcae commit 467121c
Show file tree
Hide file tree
Showing 9 changed files with 394 additions and 837 deletions.
71 changes: 10 additions & 61 deletions third_party/libtock-drivers/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,67 +1,16 @@
[package]
name = "libtock"
version = "0.2.0"
authors = ["Tock Project Developers <[email protected]>"]
name = "libtock_drivers"
version = "0.1.0"
authors = [
"Tock Project Developers <[email protected]>"
"Guillaume Endignoux <[email protected]>",
]
license = "MIT/Apache-2.0"
edition = "2018"

[features]
alloc = ["libtock_core/alloc"]
custom_panic_handler = ["libtock_core/custom_panic_handler"]
custom_alloc_error_handler = ["libtock_core/custom_alloc_error_handler"]
__internal_disable_gpio_in_integration_test = []

[dependencies]
libtock_core = { path = "core" }
libtock_codegen = { path = "codegen" }
futures = { version = "0.3.1", default-features = false, features = ["unstable", "cfg-target-has-atomic"] }

[dev-dependencies]
corepack = { version = "0.4.0", default-features = false, features = ["alloc"] }
# We pin the serde version because newer serde versions may not be compatible
# with the nightly toolchain used by libtock-rs.
serde = { version = "=1.0.84", default-features = false, features = ["derive"] }

[[example]]
name = "alloc_error"
path = "examples-features/alloc_error.rs"
required-features = ["alloc", "custom_alloc_error_handler"]

[[example]]
name = "ble_scanning"
path = "examples-features/ble_scanning.rs"
required-features = ["alloc"]

[[example]]
name = "libtock_test"
path = "examples-features/libtock_test.rs"
required-features = ["alloc"]
libtock_core = { path = "../../third_party/libtock-rs/core" }

[[example]]
name = "panic"
path = "examples-features/panic.rs"
required-features = ["custom_panic_handler"]

[[example]]
name = "simple_ble"
path = "examples-features/simple_ble.rs"
required-features = ["alloc"]

[profile.dev]
panic = "abort"
lto = true
debug = true

[profile.release]
panic = "abort"
lto = true
debug = true

[workspace]
exclude = [ "tock" ]
members = [
"codegen",
"core",
"test_runner",
"tools/print_sizes",
]
[features]
debug_ctap = []
verbose_usb = ["debug_ctap"]
191 changes: 97 additions & 94 deletions third_party/libtock-drivers/src/buttons.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
use crate::callback::CallbackSubscription;
use crate::callback::Consumer;
use crate::result::OtherError;
use crate::result::OutOfRangeError;
use crate::result::TockResult;
use crate::syscalls;
use crate::result::{OtherError, TockResult};
use core::marker::PhantomData;
use libtock_core::callback::{CallbackSubscription, Consumer};
use libtock_core::syscalls;

const DRIVER_NUMBER: usize = 0x00003;

Expand All @@ -19,87 +16,98 @@ mod subscribe_nr {
pub const SUBSCRIBE_CALLBACK: usize = 0;
}

#[non_exhaustive]
pub struct ButtonsDriverFactory;

impl ButtonsDriverFactory {
pub fn init_driver(&mut self) -> TockResult<ButtonsDriver> {
let buttons_driver = ButtonsDriver {
num_buttons: syscalls::command(DRIVER_NUMBER, command_nr::COUNT, 0, 0)?,
lifetime: PhantomData,
};
Ok(buttons_driver)
}
pub fn with_callback<CB>(callback: CB) -> WithCallback<CB> {
WithCallback { callback }
}

pub struct ButtonsDriver<'a> {
num_buttons: usize,
lifetime: PhantomData<&'a ()>,
pub struct WithCallback<CB> {
callback: CB,
}

impl<'a> ButtonsDriver<'a> {
pub fn num_buttons(&self) -> usize {
self.num_buttons
struct ButtonConsumer;

impl<CB: FnMut(usize, ButtonState)> Consumer<WithCallback<CB>> for ButtonConsumer {
fn consume(data: &mut WithCallback<CB>, button_num: usize, state: usize, _: usize) {
(data.callback)(button_num, state.into());
}
}

/// Returns the button at 0-based index `button_num`
pub fn get(&self, button_num: usize) -> Result<Button, OutOfRangeError> {
if button_num < self.num_buttons {
Ok(Button {
button_num,
lifetime: PhantomData,
})
} else {
Err(OutOfRangeError)
}
impl<CB: FnMut(usize, ButtonState)> WithCallback<CB> {
pub fn init(&mut self) -> TockResult<Buttons> {
let count = syscalls::command(DRIVER_NUMBER, command_nr::COUNT, 0, 0)?;

let subscription = syscalls::subscribe::<ButtonConsumer, _>(
DRIVER_NUMBER,
subscribe_nr::SUBSCRIBE_CALLBACK,
self,
)?;

Ok(Buttons {
count: count as usize,
subscription,
})
}
}

pub fn buttons(&self) -> Buttons {
Buttons {
num_buttons: self.num_buttons,
pub struct Buttons<'a> {
count: usize,
#[allow(dead_code)] // Used in drop
subscription: CallbackSubscription<'a>,
}

#[derive(Copy, Clone, Debug)]
pub enum ButtonsError {
NotSupported,
SubscriptionFailed,
}

impl<'a> Buttons<'a> {
pub fn iter_mut(&mut self) -> ButtonIter {
ButtonIter {
curr_button: 0,
button_count: self.count,
lifetime: PhantomData,
}
}

pub fn subscribe<CB: Fn(usize, ButtonState)>(
&self,
callback: &'a mut CB,
) -> TockResult<CallbackSubscription> {
syscalls::subscribe::<ButtonsEventConsumer, _>(
DRIVER_NUMBER,
subscribe_nr::SUBSCRIBE_CALLBACK,
callback,
)
.map_err(Into::into)
}
}

struct ButtonsEventConsumer;
#[derive(Copy, Clone, Debug)]
pub enum ButtonState {
Pressed,
Released,
}

impl<CB: Fn(usize, ButtonState)> Consumer<CB> for ButtonsEventConsumer {
fn consume(callback: &mut CB, button_num: usize, button_state: usize, _: usize) {
let button_state = match button_state {
impl From<usize> for ButtonState {
fn from(state: usize) -> ButtonState {
match state {
0 => ButtonState::Released,
1 => ButtonState::Pressed,
_ => return,
};
callback(button_num, button_state);
_ => unreachable!(),
}
}
}

pub struct Buttons<'a> {
num_buttons: usize,
impl<'a, 'b> IntoIterator for &'b mut Buttons<'a> {
type Item = ButtonHandle<'b>;
type IntoIter = ButtonIter<'b>;

fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}

pub struct ButtonIter<'a> {
curr_button: usize,
button_count: usize,
lifetime: PhantomData<&'a ()>,
}

impl<'a> Iterator for Buttons<'a> {
type Item = Button<'a>;
impl<'a> Iterator for ButtonIter<'a> {
type Item = ButtonHandle<'a>;

fn next(&mut self) -> Option<Self::Item> {
if self.curr_button < self.num_buttons {
let item = Button {
if self.curr_button < self.button_count {
let item = ButtonHandle {
button_num: self.curr_button,
lifetime: PhantomData,
};
Expand All @@ -111,57 +119,52 @@ impl<'a> Iterator for Buttons<'a> {
}
}

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ButtonState {
Pressed,
Released,
}

impl From<ButtonState> for bool {
fn from(button_state: ButtonState) -> Self {
match button_state {
ButtonState::Released => false,
ButtonState::Pressed => true,
}
}
}

pub struct Button<'a> {
pub struct ButtonHandle<'a> {
button_num: usize,
lifetime: PhantomData<&'a ()>,
}

impl<'a> Button<'a> {
pub fn button_num(&self) -> usize {
self.button_num
}

pub fn read(&self) -> TockResult<ButtonState> {
let button_state = syscalls::command(DRIVER_NUMBER, command_nr::READ, self.button_num, 0)?;
match button_state {
0 => Ok(ButtonState::Released),
1 => Ok(ButtonState::Pressed),
_ => Err(OtherError::ButtonsDriverInvalidState.into()),
}
}

pub fn enable_interrupt(&self) -> TockResult<()> {
impl<'a> ButtonHandle<'a> {
pub fn enable(&mut self) -> TockResult<Button> {
syscalls::command(
DRIVER_NUMBER,
command_nr::ENABLE_INTERRUPT,
self.button_num,
0,
)?;
Ok(())

Ok(Button { handle: self })
}

pub fn disable_interrupt(&self) -> TockResult<()> {
pub fn disable(&mut self) -> TockResult<()> {
syscalls::command(
DRIVER_NUMBER,
command_nr::DISABLE_INTERRUPT,
self.button_num,
0,
)?;

Ok(())
}
}

pub struct Button<'a> {
handle: &'a ButtonHandle<'a>,
}

#[derive(Copy, Clone, Debug)]
pub enum ButtonError {
ActivationFailed,
}

impl<'a> Button<'a> {
pub fn read(&self) -> TockResult<ButtonState> {
let button_state =
syscalls::command(DRIVER_NUMBER, command_nr::READ, self.handle.button_num, 0)?;
match button_state {
0 => Ok(ButtonState::Released),
1 => Ok(ButtonState::Pressed),
_ => Err(OtherError::ButtonsDriverInvalidState.into()),
}
}
}
Loading

0 comments on commit 467121c

Please sign in to comment.