avr-oxide 0.0.5

An extremely simple Rusty operating system for AVR microcontrollers
/* mod.rs
 *
 * Developed by Tim Walls <tim.walls@snowgoons.com>
 * Copyright (c) All Rights Reserved, Tim Walls
 */
//! ATmega4809 implementations of the generic device traits
use crate::hal::generic::debugled::DebugLed;
use crate::hal::generic::serial::SerialNoInterruptTx;

pub mod cpu;
pub mod timer;
pub mod port;
pub mod hardware;
pub mod debugled;
pub mod watchdog;
pub mod serial;

#[cfg(any(feature="stdout_usart0",feature="stdout_usart1",feature="stdout_usart2",feature="stdout_usart3"))]
use crate::stdout;




#[cfg(feature="panic_handler")]
#[panic_handler]
//#[cfg(target_arch="avr")]
fn panic(info: &core::panic::PanicInfo) -> ! {
  unsafe {
    crate::hal::concurrency::interrupt::disable_interrupts();

    #[cfg(any(feature="stdout_usart0",feature="stdout_usart1",feature="stdout_usart2",feature="stdout_usart3"))]
    {
      let serial = stdout!();

      // Remember, at the moment we can't do division involving 32 bit
      // numbers, because of Rust/LLVM/AVR bugs 🙄🙄🙄
      // @todo rework this so I can print 32 bit numbers without using 32bit
      //       maths.
      fn print_u16(val: u16) {
        if val > 9 {
          print_u16(val/10);
        }
        stdout!().blocking_write_u8(((val % 10) + 0x30) as u8);
      }

      // This doesn't look too pretty, but we can't use any of the standard
      // formatting routines because they require an allocator, which even
      // if we have one, is probably broken right now.
      // Plus the standard formatter routines don't know that we can't use
      // 32 bit arithmetic at the moment 😖
      serial.blocking_write_slice(b"\n\nPanic:\n");
      if let Some(location) = info.location() {
        serial.blocking_write_slice(b"   --> ");
        serial.blocking_write_slice(location.file().as_bytes());
        serial.blocking_write_u8(b':');
        print_u16(location.line() as u16);
        serial.blocking_write_u8(b':');
        print_u16(location.column() as u16);
        serial.blocking_write_u8(b'\n');
      }
    }

    loop {
      crate::hal::atmega4809::debugled::PinE2DebugLed::toggle();
      for _i in 0..255 {
        crate::hal::generic::busy_loop(255);
      }
    }
  }
}

const ADDR_CPU:     u16 = 0x0030;
const ADDR_CLKCTRL: u16 = 0x0060;
const ADDR_PORTA:   u16 = 0x0400;
const ADDR_PORTB:   u16 = 0x0420;
const ADDR_PORTC:   u16 = 0x0440;
const ADDR_PORTD:   u16 = 0x0460;
const ADDR_PORTE:   u16 = 0x0480;
const ADDR_PORTF:   u16 = 0x04A0;
const ADDR_PORTMUX: u16 = 0x05E0;
const ADDR_USART0:  u16 = 0x0800;
const ADDR_USART1:  u16 = 0x0820;
const ADDR_USART2:  u16 = 0x0840;
const ADDR_USART3:  u16 = 0x0860;
const ADDR_TCB0:    u16 = 0x0A80;
const ADDR_TCB1:    u16 = 0x0A90;
const ADDR_TCB2:    u16 = 0x0AA0;
const ADDR_TCB3:    u16 = 0x0AB0;
const ADDR_WDT:     u16 = 0x0100;