-
Notifications
You must be signed in to change notification settings - Fork 109
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
Button driver #369
Button driver #369
Conversation
The intended design was more like: use libtock_platform::{ErrorCode, share, subscribe, Subscribe, Upcall};
pub enum ButtonEvent {
Pressed,
Released,
}
pub struct ButtonListener<F: Fn(idx: u32, event: ButtonEvent)>(fcn: F);
impl<F: Fn(idx: u32, event: ButtonEvent)> Upcall<subscribe::OneId<3, 0>> for ButtonListener<F> {
fn upcall(&self, idx: u32, pressed: u32, _arg2: u32) {
// I'm omitting error handling for the case where pressed is not 0 or 1 here to keep code size down.
// I suspect that coercing non-1 values into 1 results in the smallest code on most architectures.
let event = match pressed {
0 => ButtonEvent::Released,
_ => ButtonEvent::Pressed,
};
self.fcn(idx, event);
}
}
pub struct Button<S: Syscalls>(S);
impl<S: Syscalls> Button<S> {
fn register_listener<'share, F: Fn(idx: u32, event: ButtonEvent)>(
&self, listener: &'share ButtonListener<F>, subscribe: share::Handle<Subscribe<'share, S, 3, 0>>)
-> Result<(), ErrorCode>
{
S::subscribe(subscribe, listener)
}
} The |
This makes sense, thank you for the feedback, I'll redesign it. I do have a question related to the pub async fn wait_switch_pressed<'share>(
button: u32,
subscribe: Handle<'_, Subscribe<'share, S, DRIVER_ID, 0>>,
) -> Result<(), ErrorCode> {
let called = Cell::<Option<(u32, u32)>>::new(None);
Self::enable_interrupts(button)?;
S::subscribe::<_, _, DefaultConfig, DRIVER_ID, 0>(subscribe, &called)?;
futures::wait_until(|| {
if let Some((pressed_button, 1)) = called.get() {
button == pressed_button
} else {
false
}
})
.await;
S::unsubscribe(DRIVER_ID, 0);
let _ = Self::disable_interrupts(button);
Ok(())
} The problem that I am facing is that share::scope(|subscribe| {
futures::block_on(async {
Button::wait_for_pressed(0, subscribe).await;
});
}); As the |
I wasn't planning to add any Futures-based APIs to |
7194a1f
to
981db1b
Compare
I redesigned the API and deleted the usage of |
bors d+ IIRC, this PR is not waiting on anything. |
✌️ alexandruradovici can now approve this pull request. To approve and merge a pull request, simply reply with |
bors r+ |
The PR adds the button driver. Reading the number of buttons and their states work.
@jrvanwhy I am not sure if I used the subscribe correctly. The idea is to provide two subscribe related functions:
wait_for_pressed
andwait_for_released
using futures that await the press or release of a button. I could not figure out how to use futures here, asshare::scope
is not async;register_for_events
that takes two closures, one called when ever there is button press or release and another one that allows apps to run code while being subscribed. I am not sure if this is the exact intended use of the subscribe system call.