Update third_party/libtock-drivers to support OpenSK.

This commit is contained in:
Guillaume Endignoux
2020-07-10 10:11:07 +02:00
parent 5f1fcaedf5
commit 467121c962
9 changed files with 414 additions and 857 deletions

View File

@@ -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;
@@ -19,87 +16,98 @@ mod subscribe_nr {
pub const SUBSCRIBE_CALLBACK: usize = 0;
}
#[non_exhaustive]
pub struct ButtonsDriverFactory;
pub fn with_callback<CB>(callback: CB) -> WithCallback<CB> {
WithCallback { callback }
}
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 struct WithCallback<CB> {
callback: CB,
}
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());
}
}
pub struct ButtonsDriver<'a> {
num_buttons: usize,
lifetime: PhantomData<&'a ()>,
}
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)?;
impl<'a> ButtonsDriver<'a> {
pub fn num_buttons(&self) -> usize {
self.num_buttons
}
/// 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)
}
}
pub fn buttons(&self) -> Buttons {
Buttons {
num_buttons: self.num_buttons,
curr_button: 0,
lifetime: PhantomData,
}
}
pub fn subscribe<CB: Fn(usize, ButtonState)>(
&self,
callback: &'a mut CB,
) -> TockResult<CallbackSubscription> {
syscalls::subscribe::<ButtonsEventConsumer, _>(
let subscription = syscalls::subscribe::<ButtonConsumer, _>(
DRIVER_NUMBER,
subscribe_nr::SUBSCRIBE_CALLBACK,
callback,
)
.map_err(Into::into)
}
}
self,
)?;
struct ButtonsEventConsumer;
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 {
0 => ButtonState::Released,
1 => ButtonState::Pressed,
_ => return,
};
callback(button_num, button_state);
Ok(Buttons {
count: count as usize,
subscription,
})
}
}
pub struct Buttons<'a> {
num_buttons: usize,
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,
}
}
}
#[derive(Copy, Clone, Debug)]
pub enum ButtonState {
Pressed,
Released,
}
impl From<usize> for ButtonState {
fn from(state: usize) -> ButtonState {
match state {
0 => ButtonState::Released,
1 => ButtonState::Pressed,
_ => unreachable!(),
}
}
}
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,
};
@@ -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()),
}
}
}