embedded_sdmmc/fat/
info.rs1use crate::{BlockCount, BlockIdx, ClusterId};
2use byteorder::{ByteOrder, LittleEndian};
3
4#[cfg_attr(feature = "defmt-log", derive(defmt::Format))]
6#[derive(Debug, Clone, Eq, PartialEq)]
7pub enum FatSpecificInfo {
8 Fat16(Fat16Info),
10 Fat32(Fat32Info),
12}
13
14#[cfg_attr(feature = "defmt-log", derive(defmt::Format))]
16#[derive(Debug, Clone, Eq, PartialEq)]
17pub struct Fat32Info {
18 pub(crate) first_root_dir_cluster: ClusterId,
21 pub(crate) info_location: BlockIdx,
23}
24
25#[cfg_attr(feature = "defmt-log", derive(defmt::Format))]
27#[derive(Debug, Clone, Eq, PartialEq)]
28pub struct Fat16Info {
29 pub(crate) first_root_dir_block: BlockCount,
32 pub(crate) root_entries_count: u16,
34}
35
36pub struct InfoSector<'a> {
43 data: &'a [u8; 512],
44}
45
46impl<'a> InfoSector<'a> {
47 const LEAD_SIG: u32 = 0x4161_5252;
48 const STRUC_SIG: u32 = 0x6141_7272;
49 const TRAIL_SIG: u32 = 0xAA55_0000;
50
51 pub fn create_from_bytes(data: &[u8; 512]) -> Result<InfoSector, &'static str> {
53 let info = InfoSector { data };
54 if info.lead_sig() != Self::LEAD_SIG {
55 return Err("Bad lead signature on InfoSector");
56 }
57 if info.struc_sig() != Self::STRUC_SIG {
58 return Err("Bad struc signature on InfoSector");
59 }
60 if info.trail_sig() != Self::TRAIL_SIG {
61 return Err("Bad trail signature on InfoSector");
62 }
63 Ok(info)
64 }
65
66 define_field!(lead_sig, u32, 0);
67 define_field!(struc_sig, u32, 484);
68 define_field!(free_count, u32, 488);
69 define_field!(next_free, u32, 492);
70 define_field!(trail_sig, u32, 508);
71
72 pub fn free_clusters_count(&self) -> Option<u32> {
74 match self.free_count() {
75 0xFFFF_FFFF => None,
76 n => Some(n),
77 }
78 }
79
80 pub fn next_free_cluster(&self) -> Option<ClusterId> {
82 match self.next_free() {
83 0xFFFF_FFFF | 0 | 1 => None,
85 n => Some(ClusterId(n)),
86 }
87 }
88}
89
90