avr-oxide 0.4.0

An extremely simple Rusty operating system for AVR microcontrollers
/* serial.rs
 *
 * Developed by Tim Walls <tim.walls@snowgoons.com>
 * Copyright (c) All Rights Reserved, Tim Walls
 */
//! ATmega4809-specific serial device declaration/implementation

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


// Declarations ==============================================================


#[cfg(feature="panicout_usart0")]
pub mod panicout {
  #[doc(hidden)]
  #[macro_export]
  macro_rules! panic_stdout { () => { avr_oxide::concurrency::interrupt::isolated(|isotoken|{ avr_oxide::hal::atmega4809::serial::usart0::instance_isolated(isotoken) })}}
}

#[cfg(feature="panicout_usart1")]
pub mod panicout {
  #[doc(hidden)]
  #[macro_export]
  macro_rules! panic_stdout { () => { avr_oxide::concurrency::interrupt::isolated(|isotoken|{ avr_oxide::hal::atmega4809::serial::usart1::instance_isolated(isotoken) })}}
}
#[cfg(feature="panicout_usart2")]
pub mod panicout {
  #[doc(hidden)]
  #[macro_export]
  macro_rules! panic_stdout { () => { avr_oxide::concurrency::interrupt::isolated(|isotoken|{ avr_oxide::hal::atmega4809::serial::usart2::instance_isolated(isotoken) })}}
}
#[cfg(feature="panicout_usart3")]
pub mod panicout {
  #[doc(hidden)]
  #[macro_export]
  macro_rules! panic_stdout { () => { avr_oxide::concurrency::interrupt::isolated(|isotoken|{ avr_oxide::hal::atmega4809::serial::usart3::instance_isolated(isotoken) })}}
}

// Code ======================================================================
#[cfg(feature="usart0")]
pub mod usart0 {
  use avr_oxide::{atmel_0series_usart_tpl};
  #[cfg(target_arch="avr")]
  use avr_oxide::hal::atmega4809::cpu::PortmuxControl;
  use avr_oxide::hal::generic::MuxControl;

  pub enum SerialPortPins {
    PortAlow,
    PortAhi,
    NotConnected
  }


  impl MuxControl for SerialPortPins {
    #[cfg(target_arch="avr")]
    fn route(&self) {
      unsafe {
        let pmux : &mut PortmuxControl = core::mem::transmute(super::super::ADDR_PORTMUX);
        let routectl = &mut pmux.usartroutea as *mut u8;


        let current = core::ptr::read_volatile(routectl);
        let mask    = 0b00000011;
        core::ptr::write_volatile(routectl,
                                  (current & !mask) | match self {
                                    SerialPortPins::PortAlow => 0b000000_00,
                                    SerialPortPins::PortAhi => 0b000000_01,
                                    SerialPortPins::NotConnected => 0b000000_11
                                  });
      }
    }

    #[cfg(not(target_arch="avr"))]
    fn route(&self) {
      println!("*** USART:PORTMUX: Routed portmux");
    }
  }

  atmel_0series_usart_tpl!(super::super::ADDR_USART0,
    avr_oxide::hal::generic::serial::SerialPortIdentity::Usart0,
    avr_oxide::hal::generic::serial::base::zeroseries::AtmelUsart<SerialPortPins, {avr_oxide::deviceconsts::oxide::SERIAL_BUFFER}>,
    "usart0_rcx", "usart0_tcx", "usart0_dre");


}

#[cfg(feature="usart1")]
pub mod usart1 {
  use avr_oxide::{atmel_0series_usart_tpl};
  #[cfg(target_arch="avr")]
  use avr_oxide::hal::atmega4809::cpu::PortmuxControl;
  use avr_oxide::hal::generic::MuxControl;

  pub enum SerialPortPins {
    PortClow,
    PortChi,
    NotConnected
  }
  impl MuxControl for SerialPortPins {
    #[cfg(target_arch="avr")]
    fn route(&self) {
      unsafe {
        let pmux : &mut PortmuxControl = core::mem::transmute(super::super::ADDR_PORTMUX);
        let routectl = &mut pmux.usartroutea as *mut u8;

        let current = core::ptr::read_volatile(routectl);
        let mask    = 0b00001100;
        core::ptr::write_volatile(routectl,
                                  (current & !mask) | match self {
                                    SerialPortPins::PortClow => 0b0000_00_00,
                                    SerialPortPins::PortChi => 0b0000_01_00,
                                    SerialPortPins::NotConnected => 0b0000_11_00
                                  });
      }
    }

    #[cfg(not(target_arch="avr"))]
    fn route(&self) {
      println!("*** USART:PORTMUX: Routed portmux");
    }
  }

  atmel_0series_usart_tpl!(super::super::ADDR_USART1,
    avr_oxide::hal::generic::serial::SerialPortIdentity::Usart1,
    avr_oxide::hal::generic::serial::base::zeroseries::AtmelUsart<SerialPortPins, {avr_oxide::deviceconsts::oxide::SERIAL_BUFFER}>,
    "usart1_rcx", "usart1_tcx", "usart1_dre");
}

#[cfg(feature="usart2")]
pub mod usart2 {
  use avr_oxide::{atmel_0series_usart_tpl};
  #[cfg(target_arch="avr")]
  use avr_oxide::hal::atmega4809::cpu::PortmuxControl;
  use avr_oxide::hal::generic::MuxControl;

  pub enum SerialPortPins {
    PortFlow,
    PortFhi,
    NotConnected
  }
  impl MuxControl for SerialPortPins {
    #[cfg(target_arch="avr")]
    fn route(&self) {
      unsafe {
        let pmux : &mut PortmuxControl = core::mem::transmute(super::super::ADDR_PORTMUX);
        let routectl = &mut pmux.usartroutea as *mut u8;

        let current = core::ptr::read_volatile(routectl);
        let mask    = 0b00110000;
        core::ptr::write_volatile(routectl,
                                  (current & !mask) | match self {
                                    SerialPortPins::PortFlow => 0b00_00_0000,
                                    SerialPortPins::PortFhi => 0b00_01_0000,
                                    SerialPortPins::NotConnected => 0b00_11_0000
                                  });
      }
    }

    #[cfg(not(target_arch="avr"))]
    fn route(&self) {
      println!("*** USART:PORTMUX: Routed portmux");
    }
  }

  atmel_0series_usart_tpl!(super::super::ADDR_USART2,
    avr_oxide::hal::generic::serial::SerialPortIdentity::Usart2,
    avr_oxide::hal::generic::serial::base::zeroseries::AtmelUsart<SerialPortPins, {avr_oxide::deviceconsts::oxide::SERIAL_BUFFER}>,
    "usart2_rcx", "usart2_tcx", "usart2_dre");


}

#[cfg(feature="usart3")]
pub mod usart3 {
  use avr_oxide::{atmel_0series_usart_tpl};
  #[cfg(target_arch="avr")]
  use avr_oxide::hal::atmega4809::cpu::PortmuxControl;
  use avr_oxide::hal::generic::MuxControl;

  pub enum SerialPortPins {
    PortBlow,
    PortBhi,
    NotConnected
  }
  impl MuxControl for SerialPortPins {
    #[cfg(target_arch="avr")]
    #[allow(clippy::unusual_byte_groupings)]
    fn route(&self) {
      unsafe {
        let pmux : &mut PortmuxControl = core::mem::transmute(super::super::ADDR_PORTMUX);
        let routectl = &mut pmux.usartroutea as *mut u8;

        let current = core::ptr::read_volatile(routectl);
        let mask    = 0b11000000;
        core::ptr::write_volatile(routectl,
                                  (current & !mask) | match self {
                                    SerialPortPins::PortBlow => 0b00_000000,
                                    SerialPortPins::PortBhi => 0b01_000000,
                                    SerialPortPins::NotConnected => 0b11_000000
                                  });
      }
    }

    #[cfg(not(target_arch="avr"))]
    fn route(&self) {
      println!("*** USART:PORTMUX: Routed portmux");
    }
  }

  atmel_0series_usart_tpl!(super::super::ADDR_USART3,
    avr_oxide::hal::generic::serial::SerialPortIdentity::Usart3,
    avr_oxide::hal::generic::serial::base::zeroseries::AtmelUsart<SerialPortPins, {avr_oxide::deviceconsts::oxide::SERIAL_BUFFER}>,
    "usart3_rcx", "usart3_tcx", "usart3_dre");
}