#![no_std]
#![allow(internal_features)]
#![feature(lang_items, fn_traits)]
#![crate_type = "staticlib"]
#[cfg(feature = "testing")]
extern crate std;
pub mod clock;
pub mod debug;
pub mod gate;
pub mod i2c;
pub mod math;
pub mod mem;
pub mod phys;
pub mod prelude;
pub mod serio;
pub mod system;
pub mod usb_serial;
use crate::clock::uNano;
use core::arch::asm;
use core::arch::global_asm;
use phys::irq::*;
use phys::pins::*;
pub const S_TO_NANO: uNano = 1000000000;
pub const MS_TO_NANO: uNano = S_TO_NANO / 1000;
pub const MICRO_TO_NANO: uNano = 1000;
#[macro_export]
macro_rules! main {
($app_code: block) => {
use teensycore::prelude::*;
pub static mut GATES: BTreeMap<u32, u32> = BTreeMap { root: None };
#[no_mangle]
pub fn main() {
loop {
disable_interrupts();
phys_clocks_en();
clock_init();
pin_mode(13, Mode::Output);
serial_init(SerioDevice::Default);
enable_interrupts();
usb_initialize();
usb_serial_init();
$app_code
}
}
#[lang = "eh_personality"]
#[no_mangle]
pub fn eh_personality() {}
#[panic_handler]
#[no_mangle]
pub fn my_panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
}
};
}
pub trait Task {
fn new() -> Self;
fn init(&mut self);
fn system_loop(&mut self);
}
#[cfg(not(feature = "testing"))]
#[macro_export]
macro_rules! assembly {
($asm: tt) => {
unsafe {
asm!($asm);
}
};
}
#[cfg(feature = "testing")]
#[macro_export]
macro_rules! assembly {
($asm: tt) => {};
}
pub fn wait_ns(nano: uNano) {
wait_exact_ns(nano);
}
#[no_mangle]
fn div(a: f32, b: f32) -> u32 {
return (a / b) as u32;
}
#[inline]
#[no_mangle]
pub fn wait_exact_ns(nano: uNano) {
let cycles = div(nano as f32 - 98.0, 7.54);
for _ in 0..cycles {
assembly!("nop");
}
}
pub fn pendsv() {
unsafe {
*((0xE000ED04) as *mut u32) = 0x10000000;
}
}
pub fn dsb() {
assembly!("dsb");
}
pub fn isb() {
assembly!("isb");
}
#[no_mangle]
pub fn arm_dcache_delete(addr: u32, size: u32) {
let mut location = addr & 0xFFFFFFE0;
let end_addr = addr + size;
dsb();
loop {
phys::assign(0xE000EF5C, location);
location += 32;
if location >= end_addr {
break;
}
}
dsb();
isb();
}
pub enum PanicType {
Hardfault,
Memfault,
Oob,
}
#[no_mangle]
pub fn err(mode: PanicType) {
disable_interrupts();
loop {
match mode {
PanicType::Hardfault => {
pin_out(13, Power::High);
}
PanicType::Oob => {
pin_out(13, Power::High);
wait_ns(MS_TO_NANO * 50);
pin_out(13, Power::Low);
wait_ns(MS_TO_NANO * 1500);
}
PanicType::Memfault => {
pin_out(13, Power::High);
wait_ns(MS_TO_NANO * 1500);
pin_out(13, Power::Low);
wait_ns(MS_TO_NANO * 50);
}
}
}
}
#[no_mangle]
fn oob() {
err(PanicType::Oob);
}
pub fn code_hash() -> u32 {
let mut result = 0;
#[cfg(not(feature = "testing"))]
unsafe {
asm!(
"mov {result}, lr",
result = inout(reg) result
);
}
return result;
}
#[cfg(not(feature = "testing"))]
global_asm!(
"
_ZN4core9panicking18panic_bounds_check17h9048f255eeb8dcc3E:
bl oob
b hang
hang:
b hang
"
);