Module avr_oxide::oxide

source ·
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
      }
    }
  });
}

Structs§

Functions§