blob: eeef4834e7a034aa13fbf6e95755c0bce9d08328 [file]
// Licensed under the Apache-2.0 license
// SPDX-License-Identifier: Apache-2.0
#![no_std]
#![no_main]
use pw_status::{Error, Result, StatusCode};
use test_uart_codegen::handle;
use userspace::syscall::Signals;
use userspace::time::Instant;
use userspace::{entry, syscall};
use registers::uart::*;
fn read_expected_value(expected_value: u8) -> Result<()> {
// the UART listener responds on IPC with the value written to the UART.
let wait_return = syscall::object_wait(handle::IPC, Signals::READABLE, Instant::MAX)?;
if !wait_return.pending_signals.contains(Signals::READABLE) || wait_return.user_data != 0 {
return Err(Error::Internal);
}
let mut buffer = [0u8; 1];
let len = syscall::channel_read(handle::IPC, 0, &mut buffer)?;
if len != 1 {
return Err(Error::OutOfRange);
};
if buffer[0] != expected_value {
pw_log::error!(
"UART read() wrong value {} (expected {})",
buffer[0] as u8,
expected_value as u8
);
return Err(Error::Internal);
}
let response_buffer = [0u8; 0];
syscall::channel_respond(handle::IPC, &response_buffer)?;
Ok(())
}
fn test_uart_interrupts() -> Result<()> {
let mut uart1 = unsafe { Uart1::new() };
let regs = uart1.regs_mut();
regs.ctrl()
.modify(|ctrl| ctrl.tx(true).rx(true).slpbk(true).nco(0xffff));
while !regs.status().read().rxempty() {
let _ = regs.rdata();
}
for txval in 65..91 {
regs.wdata().write(|w| w.wdata(txval as u32));
read_expected_value(txval)?;
}
Ok(())
}
#[entry]
fn entry() -> Result<()> {
pw_log::info!("🔄 RUNNING");
let ret = test_uart_interrupts();
if ret.is_err() {
pw_log::error!("❌ FAIL: {}", ret.status_code() as u32);
} else {
pw_log::info!("✅ PASS");
}
ret
}
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
pw_log::error!("FAIL: panic in {}", module_path!() as &str);
loop {}
}