blob: f5094086ff07aa3776cf5ec86aecf01f702897da [file]
// Licensed under the Apache-2.0 license
// SPDX-License-Identifier: Apache-2.0
//! Error code handling.
#![no_std]
use core::num::NonZero;
mod flash;
mod ipc;
mod kernel;
pub use flash::*;
pub use ipc::*;
pub use kernel::*;
/// Represents an error module.
///
/// An error module is a non-zero 16-bit identifier that categorizes a set of
/// error codes.
#[derive(Clone, Copy, PartialEq, Eq)]
#[repr(transparent)]
pub struct ErrorModule(pub NonZero<u16>);
impl ErrorModule {
/// Creates a new `ErrorModule`.
///
/// # Panics
/// Panics if `val` is zero.
pub const fn new(val: u16) -> Self {
match NonZero::new(val) {
Some(val) => Self(val),
None => panic!("ErrorModule must be non-zero"),
}
}
/// Creates an `ErrorCode` within this module.
///
/// The resulting `ErrorCode` will have the module ID in the upper 16 bits
/// and the provided `code` in the lower 16 bits.
pub const fn error(self, code: u16) -> ErrorCode {
ErrorCode::new(((self.0.get() as u32) << 16) | (code as u32))
}
/// Creates an `ErrorCode` from a Pigweed status.
///
/// This is a convenience method for creating error codes that incorporate
/// a Pigweed status.
pub const fn from_pw(self, code: u16, err: pw_status::Error) -> ErrorCode {
// pw_status::Error is 5 bits.
self.error((code << 5) | (err as u16))
}
}
/// A 32-bit error code.
///
/// An error code consists of a 16-bit module ID and a 16-bit module-specific
/// error value.
#[derive(Clone, Copy, PartialEq, Eq)]
#[repr(transparent)]
pub struct ErrorCode(pub NonZero<u32>);
impl ErrorCode {
/// Creates a new `ErrorCode`.
///
/// # Panics
/// Panics if `val` is zero.
pub const fn new(val: u32) -> Self {
match NonZero::new(val) {
Some(val) => Self(val),
None => panic!("ErrorCode must be non-zero"),
}
}
/// Creates a kernel error code from a Pigweed status.
pub fn kernel_error(e: pw_status::Error) -> Self {
KERNEL_ERROR.error(e as u16)
}
}
impl From<ErrorCode> for u32 {
fn from(e: ErrorCode) -> u32 {
e.0.get()
}
}
/*
* TODO: decide if we want ufmt or not.
use ufmt::{uDebug, uDisplay, uwrite};
impl uDisplay for ErrorCode {
fn fmt<W>(&self, f: &mut ufmt::Formatter<'_, W>) -> Result<(), W::Error>
where
W: ufmt::uWrite + ?Sized,
{
uwrite!(f, "0x{:x}", self.0.get())
}
}
impl uDebug for ErrorCode {
fn fmt<W>(&self, f: &mut ufmt::Formatter<'_, W>) -> Result<(), W::Error>
where
W: ufmt::uWrite + ?Sized,
{
uDisplay::fmt(self, f)
}
}
*/
impl core::fmt::Display for ErrorCode {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "0x{:x}", self.0.get())
}
}
impl core::fmt::Debug for ErrorCode {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
core::fmt::Display::fmt(self, f)
}
}
impl core::error::Error for ErrorCode {}