async-embedded-sdmmc 0.3.1

Embedded sdmmc driver with async support
Documentation
use displaydoc::Display;

#[derive(Copy, Clone, Debug, Display)]
pub enum TokenError {
    /// not token
    NotToken,
    /// generic
    Generic,
    /// card controller
    CC,
    /// card ECC
    CardECC,
    /// out of range
    OutOfRange,
    /// card locked
    CardLocked,
}

impl core::error::Error for TokenError {}

#[derive(Copy, Clone, Debug, PartialEq)]
#[repr(u8)]
pub enum Token {
    Start = 0xFE,
    StartWriteMultipleBlock = 0xFC,
    Stop = 0xFD,
}

impl TryFrom<u8> for Token {
    type Error = TokenError;

    fn try_from(byte: u8) -> Result<Token, TokenError> {
        match (byte, byte ^ (byte & byte.wrapping_sub(1))) {
            (0xFE, _) => Ok(Token::Start),
            (0xFC, _) => Ok(Token::StartWriteMultipleBlock),
            (_, 0x10) => Err(TokenError::CardLocked),
            (_, 0x8) => Err(TokenError::OutOfRange),
            (_, 0x4) => Err(TokenError::CardECC),
            (_, 0x2) => Err(TokenError::CC),
            (_, 0x1) => Err(TokenError::Generic),
            (_, _) => Err(TokenError::NotToken),
        }
    }
}

pub enum Response {
    Accepted,
    CRCError,
    WriteError,
}

impl Response {
    pub fn try_from(byte: u8) -> Option<Self> {
        if byte & 0b10001 != 0x1 {
            return None;
        }
        let value = match (byte >> 1) & 0b111 {
            0b010 => Self::Accepted,
            0b101 => Self::CRCError,
            0b110 => Self::WriteError,
            _ => return None,
        };
        Some(value)
    }
}