drone-micropython-stm32 0.1.1

MicroPython for Drone STM32.
//! MicroPython STM32 runtime.

use core::{mem, slice, str};
use drone_core::ffi::{c_char, c_void};
use drone_micropython_raw::{
  gc_collect_end, gc_collect_root, gc_collect_start, mp_uint_t,
};

static mut STACK_TOP: usize = 0;

#[doc(hidden)]
#[no_mangle]
pub unsafe extern "C" fn mp_hal_stdout_tx_strn(
  s: *const c_char,
  len: mp_uint_t,
) {
  print!(
    "{}",
    str::from_utf8(slice::from_raw_parts(s, len as usize)).unwrap()
  );
}

#[doc(hidden)]
#[no_mangle]
pub extern "C" fn gc_collect() {
  unsafe {
    gc_collect_start();
    let mut regs: [usize; 10] = mem::uninitialized();
    let sp: usize;
    asm!("
      str r4, [r0], #4
      str r5, [r0], #4
      str r6, [r0], #4
      str r7, [r0], #4
      str r8, [r0], #4
      str r9, [r0], #4
      str r10, [r0], #4
      str r11, [r0], #4
      str r12, [r0], #4
      str r13, [r0], #4
      mov r0, sp
    " : "={r0}"(sp)
      : "{r0}"(&mut regs)
      : "memory"
      : "volatile");
    gc_collect_root(
      sp as *mut *mut c_void,
      (STACK_TOP - sp) / mem::size_of::<usize>(),
    );
    gc_collect_end();
  }
}

pub(crate) fn init_stack() {
  unsafe {
    asm!("str sp, [$0]" :: "r"(&mut STACK_TOP) : "memory" : "volatile");
  }
}