Expand description
Simple supervisor implementation for the AVRoxide runtime.
The supervisor acts as an event sink for the device drivers’ interrupt service routines. These service routines send events to the supervisor which queues them for processing.
The queued events are then dispatched in the userland context to trigger the callback routines you provide via the device drivers.
§Usage
Obtain a reference to the supervisor using the avr_oxide::oxide::instance()
method.
Create your device driver instances and register any callbacks.
To receive events from a device driver, you must tell the supervisor
to listen to that device with the listen()
method.
Finally, call the run()
method on the supervisor to enter the main
event handling loop (never returns.)
#![no_std]
#![no_main]
use avr_oxide::alloc::boxed::Box;
use avr_oxide::devices::UsesPin;
use avr_oxide::devices::debouncer::Debouncer;
use avr_oxide::devices::{ OxideLed, OxideButton, OxideSerialPort };
use avr_oxide::boards::board;
use avr_oxide::StaticWrap;
#[avr_oxide::main(chip="atmega4809")]
pub fn main() {
let supervisor = avr_oxide::oxide::instance();
let mut green_button = StaticWrap::new(OxideButton::using(Debouncer::with_pin(board::pin_a(2))));
green_button.borrow().on_click(Box::new(move |_pinid, _state|{
// Do some processing when the button is pressed
}));
// Tell the supervisor which devices to listen to
supervisor.listen(green_button.borrow());
// Now enter the event loop
supervisor.run();
}
§Using a custom pre-event handler
You can pass a custom pre-handler closure to the run_with_prehandler()
method. This will be executed before the default event callback process
is dispatched, and returns a bool
indicating if the default event
handling process should still be followed. If this closure returns false
,
the event will be discarded without the event being passed to the device
driver.
This can be useful if you are using a Watchdog device as a way to kick the watchdog when any event is processed, regardless of source or destination.
#![no_std]
#![no_main]
use avr_oxide::alloc::boxed::Box;
use avr_oxide::devices::UsesPin;
use avr_oxide::devices::debouncer::Debouncer;
use avr_oxide::devices::{ OxideLed, OxideButton, OxideSerialPort };
use avr_oxide::boards::board;
use avr_oxide::event::OxideEvent;
use avr_oxide::StaticWrap;
#[avr_oxide::main(chip="atmega4809")]
pub fn main() {
let supervisor = avr_oxide::oxide::instance();
let mut green_button = StaticWrap::new(OxideButton::using(Debouncer::with_pin(board::pin_a(2))));
green_button.borrow().on_click(Box::new(move |_pinid, _state|{
// Do some processing when the button is pressed
}));
// Tell the supervisor which devices to listen to
supervisor.listen(green_button.borrow());
// Now enter the event loop
supervisor.run_with_prehandler(|event|{
match event {
OxideEvent::Initialise => {
// Do some custom initialisation
true
}
OxideEvent::ClockTick(_timer,_ticks) => {
// Ignore all clocktick events
false
}
_ => {
// Everything else should follow default processing
true
}
}
});
}