1use sdmmc::register::csd::Csd;
2use sdmmc::register::ext_csd::ExtCsd;
3
4use crate::{BusMode, BusWidth, PowerMode, Timing};
5
6mod address_mode;
7mod erase_mode;
8
9pub use address_mode::AddressMode;
10pub use erase_mode::EraseMode;
11
12#[repr(C)]
14#[derive(Clone, Copy, Debug, Eq, PartialEq)]
15pub struct MmcConfig {
16 bus_mode: BusMode,
17 bus_width: BusWidth,
18 power_mode: PowerMode,
19 timing: Timing,
20 slot: usize,
21 wp_grp_size: u32,
22 erase_size: usize,
23 erase_mode: EraseMode,
24 address_mode: AddressMode,
25 csd: Csd,
26 ext_csd: ExtCsd,
27}
28
29impl MmcConfig {
30 pub const fn new() -> Self {
32 Self {
33 bus_mode: BusMode::new(),
34 bus_width: BusWidth::new(),
35 power_mode: PowerMode::new(),
36 timing: Timing::new(),
37 slot: 0,
38 wp_grp_size: 0,
39 erase_size: 0,
40 erase_mode: EraseMode::new(),
41 address_mode: AddressMode::new(),
42 csd: Csd::new(),
43 ext_csd: ExtCsd::new(),
44 }
45 }
46
47 pub const fn bus_mode(&self) -> BusMode {
49 self.bus_mode
50 }
51
52 pub fn set_bus_mode(&mut self, bus_mode: BusMode) {
54 self.bus_mode = bus_mode;
55 }
56
57 pub const fn with_bus_mode(self, bus_mode: BusMode) -> Self {
59 Self { bus_mode, ..self }
60 }
61
62 pub const fn bus_width(&self) -> BusWidth {
64 self.bus_width
65 }
66
67 pub fn set_bus_width(&mut self, bus_width: BusWidth) {
69 self.bus_width = bus_width;
70 }
71
72 pub const fn with_bus_width(self, bus_width: BusWidth) -> Self {
74 Self { bus_width, ..self }
75 }
76
77 pub const fn power_mode(&self) -> PowerMode {
79 self.power_mode
80 }
81
82 pub fn set_power_mode(&mut self, power_mode: PowerMode) {
84 self.power_mode = power_mode;
85 }
86
87 pub const fn with_power_mode(self, power_mode: PowerMode) -> Self {
89 Self { power_mode, ..self }
90 }
91
92 pub const fn timing(&self) -> Timing {
94 self.timing
95 }
96
97 pub fn set_timing(&mut self, timing: Timing) {
99 self.timing = timing;
100 }
101
102 pub const fn with_timing(self, timing: Timing) -> Self {
104 Self { timing, ..self }
105 }
106
107 pub const fn slot(&self) -> usize {
109 self.slot
110 }
111
112 pub fn set_slot(&mut self, slot: usize) {
114 self.slot = slot;
115 }
116
117 pub const fn with_slot(self, slot: usize) -> Self {
119 Self { slot, ..self }
120 }
121
122 pub const fn erase_mode(&self) -> EraseMode {
124 self.erase_mode
125 }
126
127 pub fn set_erase_mode(&mut self, erase_mode: EraseMode) {
129 self.erase_mode = erase_mode;
130 }
131
132 pub const fn with_erase_mode(self, erase_mode: EraseMode) -> Self {
134 Self { erase_mode, ..self }
135 }
136
137 pub const fn address_mode(&self) -> AddressMode {
139 self.address_mode
140 }
141
142 pub fn set_address_mode(&mut self, address_mode: AddressMode) {
144 self.address_mode = address_mode;
145 }
146
147 pub const fn with_address_mode(self, address_mode: AddressMode) -> Self {
149 Self {
150 address_mode,
151 ..self
152 }
153 }
154
155 pub const fn csd(&self) -> &Csd {
157 &self.csd
158 }
159
160 pub fn csd_mut(&mut self) -> &mut Csd {
162 &mut self.csd
163 }
164
165 pub fn set_csd(&mut self, csd: Csd) {
167 self.csd = csd;
168 }
169
170 pub const fn with_csd(self, csd: Csd) -> Self {
172 Self { csd, ..self }
173 }
174
175 pub const fn ext_csd(&self) -> &ExtCsd {
177 &self.ext_csd
178 }
179
180 pub fn ext_csd_mut(&mut self) -> &mut ExtCsd {
182 &mut self.ext_csd
183 }
184
185 pub fn set_ext_csd(&mut self, ext_csd: ExtCsd) {
187 self.ext_csd = ext_csd;
188 }
189
190 pub const fn with_ext_csd(self, ext_csd: ExtCsd) -> Self {
192 Self { ext_csd, ..self }
193 }
194
195 pub const fn wp_grp_size(&self) -> u32 {
197 self.wp_grp_size
198 }
199
200 pub fn set_wp_grp_size(&mut self) {
202 self.wp_grp_size = if self.ext_csd.erase_group_def().enable() {
203 self.ext_csd.hc_erase_grp_size().size()
204 } else {
205 self.csd.erase_size() * self.csd.wp_grp_size() as u32
206 };
207 }
208
209 pub const fn can_discard(&self) -> bool {
211 false
213 }
214
215 pub const fn can_trim(&self) -> bool {
217 self.ext_csd.sec_feature_support().sec_gb_cl_en()
218 }
219
220 pub const fn hs200(&self) -> bool {
222 match self.ext_csd.device_type() {
223 Ok(d) => d.hs200(),
224 _ => false,
225 }
226 }
227
228 pub const fn hs400(&self) -> bool {
230 match self.ext_csd.device_type() {
231 Ok(d) => d.hs400(),
232 _ => false,
233 }
234 }
235
236 pub const fn hs400es(&self) -> bool {
238 self.hs400() && self.ext_csd.strobe_support().into_inner() != 0
239 }
240
241 pub const fn erase_size(&self) -> usize {
243 self.erase_size
244 }
245
246 pub fn set_erase_size(&mut self) {
248 self.erase_size = self.csd.erase_size() as usize;
249 }
250}
251
252impl Default for MmcConfig {
253 fn default() -> Self {
254 Self::new()
255 }
256}