# drone-sd-core 0.2.2

Secure Digital cards driver for Drone.
``````//! Cyclic Redundancy Code (CRC).
//!
//! The CRC is intended to protect SD Memory Card commands, responses, and data
//! transfer against transmission errors on the SD Memory Card bus. One CRC is
//! generated for every command and checked for every response on the CMD line.
//! For data blocks, one CRC per transferred block is generated.

/// The CRC7 check is used for all commands, for all responses except type R3,
/// and for the CSD and CID registers. The CRC7 is a 7-bit value and is computed
/// as follows:
///
/// * Generator polynomial: G(x) = x<sup>7</sup> + x<sup>3</sup> + 1
/// * M(x) = (first bit) * x<sup>n</sup> + (second bit) * x<sup>n-1</sup> +
///   ...  + (last bit) * x<sup>0</sup>
/// * CRC[6...0] = Remainder [(M(x) * x<sup>7</sup>)/G(x)]
///
/// The first bit is the most left bit of the corresponding bit string (of the
/// command, response, CID or CSD).  The degree n of the polynomial is the
/// number of CRC protected bits decreased by one. The number of bits to be
/// protected is 40 for commands and responses (n = 39), and 120 for the CSD and
/// CID (n = 119).
#[derive(Default)]
pub struct Crc7(u8);

/// In the case of one DAT line usage, the CRC16 is used for payload protection
/// in block transfer mode. The CRC check sum is a 16-bit value and is computed
/// as follows:
///
/// * Generator polynomial G(x) = x<sup>16</sup> + x<sup>12</sup> +
///   x<sup>5</sup> + 1
/// * M(x) = (first bit) * x<sup>n</sup> + (second bit)* x<sup>n-1</sup> + ... +
///   (last bit) * x<sup>0</sup>
/// * CRC[15...0] = Remainder [(M(x) * x<sup>16</sup>)/G(x)]
///
/// The first bit is the first data bit of the corresponding block. The degree n
/// of the polynomial denotes the number of bits of the data block decreased by
/// one (e.g. n = 4095 for a block length of 512 bytes). The generator
/// polynomial G(x) is a standard CCITT polynomial. The code has a minimal
/// distance d = 4 and is used for a payload length of up to 2048 Bytes (n <=
/// 16383).
///
/// The same CRC16 method shall be used in single DAT line mode and in wide bus
/// mode. In wide bus mode, the CRC16 is done on each line separately.
#[derive(Default)]
pub struct Crc16(u16);

/// Generic CRC.
pub trait Crc: Default {
/// CRC output.
type Output;

/// Adds a byte to the CRC.

/// Returns the output value of the CRC.
fn value(&self) -> Self::Output;

/// Calculates a new CRC from bytes.
fn from_bytes(bytes: &[u8]) -> Self {
let mut crc = Self::default();
for &byte in bytes {
}
crc
}
}

impl Crc for Crc7 {
type Output = u8;

fn add_byte(&mut self, byte: u8) {
const G: u8 = 0x89;
self.0 ^= byte;
for _ in 0..8 {
if self.0 & 0x80 != 0 {
self.0 ^= G;
}
self.0 <<= 1;
}
}

fn value(&self) -> u8 {
self.0
}
}

impl Crc for Crc16 {
type Output = u16;

fn add_byte(&mut self, byte: u8) {
self.0 = self.0 >> 8 | self.0 << 8;
self.0 ^= u16::from(byte);
self.0 ^= (self.0 & 0xFF) >> 4;
self.0 ^= self.0 << 8 << 4;
self.0 ^= (self.0 & 0xFF) << 4 << 1;
}

fn value(&self) -> u16 {
self.0
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn cmd0() {
let mut crc = Crc7::default();
assert_eq!(crc.value(), 0b10010100);
}

#[test]
fn cmd17() {
let mut crc = Crc7::default();
assert_eq!(crc.value(), 0b01010100);
}

#[test]
fn cmd17_response() {
let mut crc = Crc7::default();