//! 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 DebugUartCapsule {
    pub app_data_grant: Grant<AppData>,
}

impl Driver for DebugUartCapsule {
    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::debug_uart::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;
    }
}
