sdmmc-core 0.5.0

SD/MMC core data structures and algorithms
Documentation
use crate::result::Result;
use crate::{RangedIndex, const_try, lib_bitfield};

use super::{ExtCsd, ExtCsdIndex};

mod direction_activation;
mod large_unit;
mod reliability_mode;

pub use direction_activation::*;
pub use large_unit::*;
pub use reliability_mode::*;

/// Represents the ID of the `CONTEXT_CONF` field in the [ExtCsd] register.
///
/// The index starts at `1`, and ends at `15`, for [ExtCsdIndex] `37` to `51`, respectively.
pub type ContextId = RangedIndex<1, 15>;

lib_bitfield! {
    /// Represents the `CONTEXT_CONF` field of the [ExtCsd] register.
    ///
    /// Each field in the `CONTEXT_CONF` range is selected by its index ID.
    ///
    /// The ID range starts at `1`, and ends at `15`. ID `0` is reserved for a context-less config.
    ContextConf: u8,
    mask: 0xff,
    default: 0x00,
    {
        /// Represents the `Reliability Mode` configuration.
        reliability_mode: ReliabilityMode, 7, 6;
        /// Represents the `Large Unit Multiplier` value.
        ///
        /// # Note
        ///
        /// Only meaningful if the `Large Unit Context` bit is set.
        large_unit_multiplier: LargeUnitMultiplier, 5, 3;
        /// Represents the `Large Unit Context` rules.
        large_unit_context: LargeUnitContext, 2;
        /// Represents the direction and activation configuration.
        direction_activation: DirectionActivation, 1, 0;
    }
}

impl ExtCsd {
    /// Represents the number of [ContextConf] fields.
    pub const CONTEXT_CONF_LEN: usize = 15;

    /// Gets the `CONTEXT_CONF` field by ID for the [ExtCsd] register.
    pub const fn context_conf(&self, id: ContextId) -> Result<ContextConf> {
        let index = ExtCsdIndex::CONTEXT_CONF_START + id.into_inner() - 1;
        ContextConf::try_from_inner(self.0[index])
    }

    /// Gets all of the `CONTEXT_CONF` fields for the [ExtCsd] register.
    pub const fn context_conf_all(&self) -> Result<[ContextConf; Self::CONTEXT_CONF_LEN]> {
        let start = ExtCsdIndex::CONTEXT_CONF_START;

        Ok([
            const_try!(ContextConf::try_from_inner(self.0[start])),
            const_try!(ContextConf::try_from_inner(self.0[start + 1])),
            const_try!(ContextConf::try_from_inner(self.0[start + 2])),
            const_try!(ContextConf::try_from_inner(self.0[start + 3])),
            const_try!(ContextConf::try_from_inner(self.0[start + 4])),
            const_try!(ContextConf::try_from_inner(self.0[start + 5])),
            const_try!(ContextConf::try_from_inner(self.0[start + 6])),
            const_try!(ContextConf::try_from_inner(self.0[start + 7])),
            const_try!(ContextConf::try_from_inner(self.0[start + 8])),
            const_try!(ContextConf::try_from_inner(self.0[start + 9])),
            const_try!(ContextConf::try_from_inner(self.0[start + 10])),
            const_try!(ContextConf::try_from_inner(self.0[start + 11])),
            const_try!(ContextConf::try_from_inner(self.0[start + 12])),
            const_try!(ContextConf::try_from_inner(self.0[start + 13])),
            const_try!(ContextConf::try_from_inner(self.0[start + 14])),
        ])
    }

    /// Sets the `CONTEXT_CONF` field by ID for the [ExtCsd] register.
    pub fn set_context_conf(&mut self, id: ContextId, context: ContextConf) {
        let index = ExtCsdIndex::CONTEXT_CONF_START + id.into_inner() - 1;
        self.0[index] = context.into_inner();
    }
}