drone-sd-core 0.2.2

Secure Digital cards driver for Drone.
//! Errors.

/// DMA communication error.
#[derive(Debug, Fail)]
pub enum DmaError {
  /// DMA receive error.
  #[fail(display = "DMA read error.")]
  Rx,
  /// DMA transmit error.
  #[fail(display = "DMA write error.")]
  Tx,
}

/// R1 response error.
#[derive(Debug, Fail)]
pub enum R1Error {
  /// Illegal Command Error.
  #[fail(display = "Illegal command.")]
  Illegal,
  /// Command CRC Error.
  #[fail(display = "Command CRC mismatch.")]
  Crc,
  /// Error in the sequence of erase commands.
  #[fail(display = "Invalid erase sequence.")]
  InvalidEraseSequence,
  /// A misaligned address error.
  #[fail(display = "Misaligned address.")]
  Address,
  /// Command Argument Error.
  #[fail(display = "Invalid argument.")]
  Parameter,
}

/// Read operation error.
#[derive(Debug, Fail)]
pub enum ReadError {
  /// General or unknown error.
  #[fail(display = "Read error.")]
  Unknown,
  /// Internal card controller error.
  #[fail(display = "Internal card error.")]
  Card,
  /// Card internal ECC was applied but failed to correct the data.
  #[fail(display = "ECC error.")]
  Ecc,
  /// The command argument was out of the allowed range for this card.
  #[fail(display = "Out of range.")]
  OutOfRange,
}

/// Write operation error.
#[derive(Debug, Fail)]
pub enum WriteError {
  /// Data rejected due to a CRC error.
  #[fail(display = "CRC error.")]
  Crc,
  /// Data Rejected due to a Write Error.
  #[fail(display = "Write error.")]
  Unknown,
  /// Set when the card is locked by the user.
  #[fail(display = "Card is locked.")]
  Locked,
  /// This status bit has two functions overloaded. It is set when the host
  /// attempts to erase a write-protected sector or makes a sequence or password
  /// errors during card lock/unlock operation.
  #[fail(display = "Erase protect violation or lock failed.")]
  WriteProtectEraseOrLockFailed,
  /// Internal card controller error.
  #[fail(display = "Internal card error.")]
  Card,
  /// Card internal ECC was applied but failed to correct the data.
  #[fail(display = "ECC error.")]
  Ecc,
  /// The command tried to write a write-protected block.
  #[fail(display = "Write protect violation.")]
  WriteProtect,
  /// An invalid selection for erase, sectors or groups.
  #[fail(display = "Erase param error.")]
  EraseParam,
  /// Can be either of the following errors:
  ///
  /// *The command argument was out of the allowed range for this card.
  /// *The read only section of the CSD does not match the card content.
  /// *An attempt to reverse the copy (set as original) or permanent WP
  /// (unprotected) bits was made.
  #[fail(display = "Out of range or CSD overwrite.")]
  OutOfRangeOrCsdOverwrite,
}

/// SD command error.
#[derive(Debug, Fail)]
pub enum CmdError {
  /// DMA communication error.
  #[fail(display = "DMA error: {}", _0)]
  Dma(DmaError),
  /// SPI communication error.
  #[fail(display = "SPI error.")]
  Spi,
  /// Command timed out.
  #[fail(display = "Command timeout.")]
  Timeout,
  /// R1 error received.
  #[fail(display = "R1 error: {}", _0)]
  R1(R1Error),
  /// Read error received.
  #[fail(display = "Read error: {}", _0)]
  Read(ReadError),
  /// Write error received.
  #[fail(display = "Write error: {}", _0)]
  Write(WriteError),
  /// Data CRC Error.
  #[fail(display = "Data CRC mismatch.")]
  DataCrc,
}

/// SPI mode initialization error.
#[derive(Debug, Fail)]
pub enum SpiInitError {
  /// SD command error.
  #[fail(display = "Command error: {}", _0)]
  Cmd(CmdError),
  /// `GO_IDLE_STATE` command failed to go idle.
  #[fail(display = "Failed to go idle.")]
  NotIdle,
  /// SD card interface condition mismatch.
  #[fail(display = "Condition mismatch.")]
  CondMismatch,
  /// Given voltage is unsupported by the card.
  #[fail(display = "Unsupported voltage.")]
  UnsupportedVoltage,
}

impl From<DmaError> for CmdError {
  #[inline(always)]
  fn from(err: DmaError) -> Self {
    CmdError::Dma(err)
  }
}

impl From<R1Error> for CmdError {
  #[inline(always)]
  fn from(err: R1Error) -> Self {
    CmdError::R1(err)
  }
}

impl From<ReadError> for CmdError {
  #[inline(always)]
  fn from(err: ReadError) -> Self {
    CmdError::Read(err)
  }
}

impl From<WriteError> for CmdError {
  #[inline(always)]
  fn from(err: WriteError) -> Self {
    CmdError::Write(err)
  }
}

impl From<DmaError> for SpiInitError {
  #[inline(always)]
  fn from(err: DmaError) -> Self {
    err.into()
  }
}

impl From<CmdError> for SpiInitError {
  #[inline(always)]
  fn from(err: CmdError) -> Self {
    SpiInitError::Cmd(err)
  }
}