//! Trivial capsule to provide minimal debug printing support for userspace.
//!
//! The default TockOS Console class does heavier-weight stuff with UART
//! multiplexing and asynchronous sending and such, which is usually _not_ what
//! is wanted in a debug serial port. This capsule implements only one command,
//! which dumps data from an allow'ed buffer directly to a memory-mapped UART
//! peripheral.
//!
//! Usage - send buffer directly to UART:
//!   let driver_num = capsules::debug_uart::DRIVER_NUM;
//!   let allow = syscalls::allow(driver_num, 0, &mut buffer);
//!   let result = syscalls::command(driver_num, 0, buffer.len(), 0);
//!   drop(allow);

use kernel::{AppId, AppSlice, Callback, Driver, Grant, ReturnCode, Shared};

#[derive(Default)]
pub struct AppData {
    pub buffer: Option<AppSlice<Shared, u8>>,
}

pub struct DprintfCapsule {
    pub app_data_grant: Grant<AppData>,
}

impl Driver for DprintfCapsule {
    fn subscribe(&self, _: usize, _: Option<Callback>, _: AppId) -> ReturnCode {
        ReturnCode::EINVAL
    }

    fn command(&self, minor_num: usize, r2: usize, _: usize, app_id: AppId) -> ReturnCode {
        if minor_num != 0 {
            return ReturnCode::EINVAL;
        }

        let _ = self.app_data_grant.enter(app_id, |app_data, _| {
            if let Some(buf) = &app_data.buffer {
                matcha_hal::dprintf_hal::send_sync(buf.as_ref(), r2);
            }
        });
        return ReturnCode::SUCCESS;
    }

    fn allow(&self, app_id: AppId, _: usize, slice: Option<AppSlice<Shared, u8>>) -> ReturnCode {
        let _ = self.app_data_grant.enter(app_id, |app_data, _| {
            app_data.buffer = slice;
        });
        return ReturnCode::SUCCESS;
    }
}
