avr-oxide 0.4.0

An extremely simple Rusty operating system for AVR microcontrollers
/* arduino.rs
 *
 * Developed by Tim Walls <tim.walls@snowgoons.com>
 * Copyright (c) All Rights Reserved, Tim Walls
 */
//! A helper module that maps standard ATmega pins into equivalent Arduino
//! names through helper functions [`board::pin_a()`] and [`board::pin_d()`].
//!
//! ```rust,no_run
//! use avr_oxide::boards;
//! use avr_oxide::hal::generic::port::{ Pin, PinMode };
//!
//! fn use_arduino_types() {
//!   // We can now refer to Pord D, pin 3 on an Arduino Nano Every as
//!   // `arduino::board::pin_a(0)` if compiled with feature `arduino_nanoevery`
//!   boards::nanoevery::pin_a(0).set_mode(PinMode::Output);
//!   boards::nanoevery::pin_a(0).set_high();
//! }
//! ```
//!
//! # Features
//!
//! | Feature name |         |
//! | ------------ | ------- |
//! | `arduino_nanoevery`       | Arduino Nano Every with ATmega4809 CPU |
//! | `arduino_uno`             | Arduino Uno with ATmega328P CPU |
//! | `atmega4809_xplained_pro` | AVR ATMega4809-XPlained-Pro board |
//!

// Imports ===================================================================

// Declarations ==============================================================
#[cfg(feature="arduino_uno")]
pub use uno as board;

#[cfg(feature="arduino_nanoevery")]
pub use nanoevery as board;

#[cfg(feature="atmega_xplained")]
pub use xplained as board;

#[cfg(feature="arduino_uno")]
/// Arduino Uno board access aliases
pub mod uno {
  use avr_oxide::hal::generic::port::{Pin, PinMode};

  /// Return the Pin device associated with the given Arduino Analagoue pin
  pub fn pin_a(pin: u8) -> &'static dyn Pin {
    match pin {
      0 => avr_oxide::hardware::port::portc::pin(0),
      1 => avr_oxide::hardware::port::portc::pin(1),
      2 => avr_oxide::hardware::port::portc::pin(2),
      3 => avr_oxide::hardware::port::portc::pin(3),
      4 => avr_oxide::hardware::port::portc::pin(4),
      5 => avr_oxide::hardware::port::portc::pin(5),
      _ => avr_oxide::oserror::halt(avr_oxide::oserror::OsError::BadParams)
    }
  }
  /// Return the Pin device associated with the given Arduino Digital pin
  pub fn pin_d(pin: u8) -> &'static dyn Pin {
    match pin {
      0 => avr_oxide::hardware::port::portd::pin(0),
      1 => avr_oxide::hardware::port::portd::pin(1),
      2 => avr_oxide::hardware::port::portd::pin(2),
      3 => avr_oxide::hardware::port::portd::pin(3),
      4 => avr_oxide::hardware::port::portd::pin(4),
      5 => avr_oxide::hardware::port::portd::pin(5),
      6 => avr_oxide::hardware::port::portd::pin(6),
      7 => avr_oxide::hardware::port::portd::pin(7),
      8 => avr_oxide::hardware::port::portb::pin(0),
      9 => avr_oxide::hardware::port::portb::pin(1),
      10 => avr_oxide::hardware::port::portb::pin(2),
      11 => avr_oxide::hardware::port::portb::pin(3),
      12 => avr_oxide::hardware::port::portb::pin(4),
      13 => avr_oxide::hardware::port::portb::pin(5),
      _ => avr_oxide::oserror::halt(avr_oxide::oserror::OsError::BadParams)
    }
  }
  /// Return the Pin device associated with the Arduino's debugging LED
  pub fn debug_pin() -> &'static dyn Pin {
    avr_oxide::hardware::port::portb::pin(5)
  }

  /// Get the serial device associated with the Arduino's USB serial port
  pub fn usb_serial() -> &'static mut avr_oxide::hardware::serial::usart0::SerialImpl {
    avr_oxide::concurrency::interrupt::isolated(|isotoken|{
      avr_oxide::hardware::serial::usart0::instance_isolated(isotoken)
    })
  }
  /// Get the pins (returned as a tuple (TX,RX)) associated with the
  /// Arduino's USB serial port
  pub fn usb_serial_pins() -> (&'static dyn Pin, &'static dyn Pin) {
    (avr_oxide::hardware::port::portd::pin(1),avr_oxide::hardware::port::portd::pin(0))
  }

  /// Do any Arduino board specific initialisation
  pub fn initialise() {
    debug_pin().set_mode(PinMode::Output);
    debug_pin().set_low();
    avr_oxide::oserror::set_debug_pin(debug_pin());
  }
}

#[cfg(feature="arduino_nanoevery")]
/// Arduino Nano Every board access aliases
pub mod nanoevery {
  use avr_oxide::hal::generic::port::{Pin, PinMode};

  /// Return the Pin device associated with the given Arduino Analagoue pin
  pub fn pin_a(pin: u8) -> &'static dyn Pin {
    match pin {
      0 => avr_oxide::hardware::port::portd::pin(3),
      1 => avr_oxide::hardware::port::portd::pin(2),
      2 => avr_oxide::hardware::port::portd::pin(1),
      3 => avr_oxide::hardware::port::portd::pin(0),
      4 => avr_oxide::hardware::port::porta::pin(2),
      5 => avr_oxide::hardware::port::porta::pin(3),
      6 => avr_oxide::hardware::port::portd::pin(4),
      7 => avr_oxide::hardware::port::portd::pin(5),
      _ => avr_oxide::oserror::halt(avr_oxide::oserror::OsError::BadParams)
    }
  }
  /// Return the Pin device associated with the given Arduino Digital pin
  pub fn pin_d(pin: u8) -> &'static dyn Pin {
    match pin {
      0 => avr_oxide::hardware::port::portc::pin(4),
      1 => avr_oxide::hardware::port::portc::pin(5),
      2 => avr_oxide::hardware::port::porta::pin(0),
      3 => avr_oxide::hardware::port::portf::pin(5),
      4 => avr_oxide::hardware::port::portc::pin(6),
      5 => avr_oxide::hardware::port::portb::pin(2),
      6 => avr_oxide::hardware::port::portf::pin(4),
      7 => avr_oxide::hardware::port::porta::pin(1),
      8 => avr_oxide::hardware::port::porte::pin(3),
      9 => avr_oxide::hardware::port::portb::pin(0),
      10 => avr_oxide::hardware::port::portb::pin(1),
      11 => avr_oxide::hardware::port::porte::pin(0),
      12 => avr_oxide::hardware::port::porte::pin(1),
      13 => avr_oxide::hardware::port::porte::pin(2),
      _ => avr_oxide::oserror::halt(avr_oxide::oserror::OsError::BadParams)
    }
  }

  /// Return the Pin device associated with the Arduino's debugging LED
  pub fn debug_pin() -> &'static dyn Pin {
    avr_oxide::hardware::port::porte::pin(2)
  }

  /// Get the serial device associated with the Arduino's USB serial port
  pub fn usb_serial() -> &'static mut avr_oxide::hardware::serial::usart3::SerialImpl {
    avr_oxide::hardware::serial::usart3::instance().mux(avr_oxide::hal::atmega4809::serial::usart3::SerialPortPins::PortBhi)
  }

  /// Get the pins (returned as a tuple (TX,RX)) associated with the
  /// Arduino's USB serial port
  pub fn usb_serial_pins() -> (&'static dyn Pin, &'static dyn Pin) {
    (avr_oxide::hardware::port::portb::pin(4),avr_oxide::hardware::port::portb::pin(5))
  }

  /// Do any board specific initialisation
  pub fn initialise() {
    debug_pin().set_mode(PinMode::Output);
    debug_pin().set_low();
    avr_oxide::oserror::set_debug_pin(debug_pin());
  }
}

#[cfg(all(feature="atmega_xplained",feature="atmega4809"))]
/// Microchip ATMega4809xplained board mapping aliases
pub mod xplained {
  use avr_oxide::devices::inverter::Inverter;
  use avr_oxide::devices::UsesPin;
  use avr_oxide::hal::generic::port::{Pin, PinMode};
  use avr_oxide::oserror::OsError;

  /// Return the pin attached to switch SW0
  pub fn sw0() -> &'static dyn Pin {
    avr_oxide::hardware::port::portb::pin(2)
  }

  /// Return the pin attached to switch SW1
  pub fn sw1() -> &'static dyn Pin {
    avr_oxide::hardware::port::portf::pin(6)
  }

  /// Return the pin attached to the on-board LED
  pub fn led0() -> &'static dyn Pin {
    avr_oxide::hardware::port::portb::pin(5)
  }


  static mut INVERTED_DEBUG : Option<Inverter> = None;

  /// Return the Pin device associated with the on-board debug LED
  pub fn debug_pin() -> &'static dyn Pin {
    unsafe {
      match &INVERTED_DEBUG {
        None => {
          avr_oxide::oserror::halt(OsError::InternalError);
        },
        Some(pin) => {
          pin
        }
      }
    }
  }

  /// Get the serial device associated with the Xplained's USB serial port
  pub fn usb_serial() -> &'static mut avr_oxide::hardware::serial::usart1::SerialImpl {
    avr_oxide::hardware::serial::usart1::instance().mux(avr_oxide::hal::atmega4809::serial::usart1::SerialPortPins::PortClow)
  }

  /// Get the pins (returned as a tuple (TX,RX)) associated with the
  /// Xplained's USB serial port
  pub fn usb_serial_pins() -> (&'static dyn Pin, &'static dyn Pin) {
    (avr_oxide::hardware::port::portc::pin(0),avr_oxide::hardware::port::portc::pin(1))
  }

  /// Do any board specific initialisation
  pub fn initialise() {
    sw0().set_mode(PinMode::InputPullup);

    unsafe {
      INVERTED_DEBUG.replace(Inverter::with_pin(led0()));
    }

    debug_pin().set_mode(PinMode::Output);
    debug_pin().set_low();
    avr_oxide::oserror::set_debug_pin(debug_pin());
  }
}

// Tests =====================================================================