1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use super::state::MemoryState;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[atomic_macro::atomic(32)]
pub struct MemoryGroup(u32);
impl MemoryGroup {
    pub const fn new() -> Self {
        Self((MemoryState::Uninitialized as u32) << 24 | 0)
    }
    pub const fn max_group() -> usize {
        0x00FF_FFFF + 1
    }
    pub fn group(&self) -> usize {
        (self.0 as usize) & 0x00FF_FFFF
    }
    pub fn set_group(&mut self, val: usize) {
        self.0 = (self.0 & 0xFF00_0000) | val as u32;
    }
    pub fn state(&self) -> MemoryState {
        ((self.0 >> 24) as u8).into()
    }
    pub fn set_state(&mut self, val: MemoryState) {
        self.0 = (self.0 & 0x00FF_FFFF) | ((u8::from(val) as u32) << 24);
    }
    pub fn next(&self) -> Self {
        let mut ret = *self;
        match self.state() {
            MemoryState::Uninitialized => ret.set_state(MemoryState::Initializing),
            MemoryState::Initializing => ret.set_state(MemoryState::Initialized),
            MemoryState::Initialized => ret.set_state(MemoryState::Erasing),
            MemoryState::Erasing => {
                let group = self.group() + 1;
                ret.set_group(if group >= Self::max_group() { 0 } else { group });
                ret.set_state(MemoryState::Uninitialized);
            }
            _ => unreachable!(),
        }
        ret
    }

    pub const fn max_idx(size: usize) -> usize {
        let group_max = Self::max_group();
        usize::MAX / size / group_max * size * group_max
    }
    pub const fn group_of_idx(idx: usize, size: usize) -> usize {
        idx / size
    }
}
impl From<u32> for MemoryGroup {
    fn from(s: u32) -> Self {
        Self(s)
    }
}
impl From<MemoryGroup> for u32 {
    fn from(s: MemoryGroup) -> Self {
        s.0
    }
}