1use core::fmt;
10use deku::prelude::*;
11
12#[cfg(not(feature = "std"))]
13use alloc::{format, string::String};
14
15use crate::SdrrInfo;
16
17pub enum Source {
19 Flash,
20 Ram,
21}
22
23#[derive(
27 Debug, Clone, Copy, PartialEq, Eq, DekuRead, DekuWrite, serde::Serialize, serde::Deserialize,
28)]
29#[deku(id_type = "u16", ctx = "endian: deku::ctx::Endian")]
30pub enum McuLine {
31 #[deku(id = "0x0000")]
33 F401DE,
34
35 #[deku(id = "0x0001")]
37 F405,
38
39 #[deku(id = "0x0002")]
41 F411,
42
43 #[deku(id = "0x0003")]
45 F446,
46
47 #[deku(id = "0x0004")]
49 F401BC,
50
51 #[deku(id = "0x0005")]
53 Rp2350,
54}
55
56impl fmt::Display for McuLine {
57 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58 match self {
59 McuLine::F401DE => write!(f, "STM32F401DE"),
60 McuLine::F405 => write!(f, "STM32F405"),
61 McuLine::F411 => write!(f, "STM32F411"),
62 McuLine::F446 => write!(f, "STM32F446"),
63 McuLine::F401BC => write!(f, "STM32F401BC"),
64 McuLine::Rp2350 => write!(f, "RP2350"),
65 }
66 }
67}
68
69impl McuLine {
70 pub fn ram_kb(&self) -> &str {
72 match self {
73 McuLine::F401DE => "96",
74 McuLine::F401BC => "64",
75 McuLine::F405 | McuLine::F411 | McuLine::F446 => "128",
76 McuLine::Rp2350 => "520",
77 }
78 }
79}
80
81#[derive(
87 Debug, Clone, Copy, PartialEq, Eq, DekuRead, DekuWrite, serde::Serialize, serde::Deserialize,
88)]
89#[deku(id_type = "u16", ctx = "endian: deku::ctx::Endian")]
90pub enum McuStorage {
91 #[deku(id = "0")]
93 Storage8,
94
95 #[deku(id = "1")]
97 StorageB,
98
99 #[deku(id = "2")]
101 StorageC,
102
103 #[deku(id = "3")]
105 StorageD,
106
107 #[deku(id = "4")]
109 StorageE,
110
111 #[deku(id = "5")]
113 StorageF,
114
115 #[deku(id = "6")]
117 StorageG,
118
119 #[deku(id = "7")]
121 Storage2MB,
122}
123
124impl McuStorage {
125 pub fn kb(&self) -> &str {
127 match self {
128 McuStorage::Storage8 => "64",
129 McuStorage::StorageB => "128",
130 McuStorage::StorageC => "256",
131 McuStorage::StorageD => "384",
132 McuStorage::StorageE => "512",
133 McuStorage::StorageF => "768",
134 McuStorage::StorageG => "1024",
135 McuStorage::Storage2MB => "2048",
136 }
137 }
138
139 pub fn package_code(&self) -> &str {
141 match self {
142 McuStorage::Storage8 => "8",
143 McuStorage::StorageB => "B",
144 McuStorage::StorageC => "C",
145 McuStorage::StorageD => "D",
146 McuStorage::StorageE => "E",
147 McuStorage::StorageF => "F",
148 McuStorage::StorageG => "G",
149 McuStorage::Storage2MB => "2MB",
150 }
151 }
152}
153
154impl fmt::Display for McuStorage {
155 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
156 write!(f, "{}", self.package_code())
157 }
158}
159
160#[derive(
164 Debug, Clone, Copy, PartialEq, Eq, DekuRead, DekuWrite, serde::Serialize, serde::Deserialize,
165)]
166#[deku(id_type = "u8")]
167pub enum SdrrRomType {
168 #[deku(id = "0")]
170 Rom2316,
171
172 #[deku(id = "1")]
174 Rom2332,
175
176 #[deku(id = "2")]
178 Rom2364,
179}
180
181impl fmt::Display for SdrrRomType {
182 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
183 match self {
184 SdrrRomType::Rom2316 => write!(f, "2316"),
185 SdrrRomType::Rom2332 => write!(f, "2332"),
186 SdrrRomType::Rom2364 => write!(f, "2364"),
187 }
188 }
189}
190
191impl SdrrRomType {
192 pub fn rom_size(&self) -> usize {
194 self.rom_size_kb() * 1024
195 }
196
197 pub fn rom_size_kb(&self) -> usize {
199 match self {
200 SdrrRomType::Rom2316 => 2,
201 SdrrRomType::Rom2332 => 4,
202 SdrrRomType::Rom2364 => 8,
203 }
204 }
205
206 pub fn max_addr(&self) -> u32 {
208 (self.rom_size() - 1) as u32
209 }
210
211 pub fn supports_cs2(&self) -> bool {
213 match self {
214 SdrrRomType::Rom2316 => true,
215 SdrrRomType::Rom2332 => true,
216 SdrrRomType::Rom2364 => false,
217 }
218 }
219
220 pub fn supports_cs3(&self) -> bool {
222 match self {
223 SdrrRomType::Rom2316 => true,
224 SdrrRomType::Rom2332 => false,
225 SdrrRomType::Rom2364 => false,
226 }
227 }
228}
229
230#[derive(
234 Debug, Clone, Copy, PartialEq, Eq, DekuRead, DekuWrite, serde::Serialize, serde::Deserialize,
235)]
236#[deku(id_type = "u8")]
237pub enum SdrrCsState {
238 #[deku(id = "0")]
240 ActiveLow,
241
242 #[deku(id = "1")]
244 ActiveHigh,
245
246 #[deku(id = "2")]
248 NotUsed,
249}
250
251impl fmt::Display for SdrrCsState {
252 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
253 match self {
254 SdrrCsState::ActiveLow => write!(f, "Active Low"),
255 SdrrCsState::ActiveHigh => write!(f, "Active High"),
256 SdrrCsState::NotUsed => write!(f, "Not Used"),
257 }
258 }
259}
260
261#[derive(
265 Debug, Clone, Copy, PartialEq, Eq, DekuRead, DekuWrite, serde::Serialize, serde::Deserialize,
266)]
267#[deku(id_type = "u8")]
268pub enum SdrrServe {
269 #[deku(id = "0")]
272 TwoCsOneAddr,
273
274 #[deku(id = "1")]
277 AddrOnCs,
278
279 #[deku(id = "2")]
282 AddrOnAnyCs,
283}
284
285impl fmt::Display for SdrrServe {
286 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
287 match self {
288 SdrrServe::TwoCsOneAddr => write!(f, "A = Two CS checks for every address check"),
289 SdrrServe::AddrOnCs => write!(f, "B = Check address only when CS active"),
290 SdrrServe::AddrOnAnyCs => write!(f, "C = Check address on any CS active"),
291 }
292 }
293}
294
295#[derive(
299 Debug, Clone, Copy, PartialEq, Eq, DekuRead, DekuWrite, serde::Serialize, serde::Deserialize,
300)]
301#[deku(id_type = "u8")]
302pub enum SdrrMcuPort {
303 #[deku(id = "0x00")]
305 None,
306
307 #[deku(id = "0x01")]
309 PortA,
310
311 #[deku(id = "0x02")]
313 PortB,
314
315 #[deku(id = "0x03")]
317 PortC,
318
319 #[deku(id = "0x04")]
321 PortD,
322
323 #[deku(id = "0x05")]
325 Port0,
326}
327
328impl fmt::Display for SdrrMcuPort {
329 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
330 match self {
331 SdrrMcuPort::None => write!(f, "None"),
332 SdrrMcuPort::PortA => write!(f, "A"),
333 SdrrMcuPort::PortB => write!(f, "B"),
334 SdrrMcuPort::PortC => write!(f, "C"),
335 SdrrMcuPort::PortD => write!(f, "D"),
336 SdrrMcuPort::Port0 => write!(f, "0"),
337 }
338 }
339}
340
341#[derive(Debug, Clone, Copy, PartialEq, Eq)]
344pub struct SdrrCsSet {
345 cs1: bool,
347
348 cs2: Option<bool>,
350
351 cs3: Option<bool>,
353
354 x1: Option<bool>,
356
357 x2: Option<bool>,
359}
360
361impl SdrrCsSet {
362 pub fn new(
364 cs1: bool,
365 cs2: Option<bool>,
366 cs3: Option<bool>,
367 x1: Option<bool>,
368 x2: Option<bool>,
369 ) -> Self {
370 Self {
371 cs1,
372 cs2,
373 cs3,
374 x1,
375 x2,
376 }
377 }
378
379 pub fn cs1(&self) -> bool {
381 self.cs1
382 }
383
384 pub fn cs2(&self) -> Option<bool> {
386 self.cs2
387 }
388
389 pub fn cs3(&self) -> Option<bool> {
391 self.cs3
392 }
393
394 pub fn x1(&self) -> Option<bool> {
396 self.x1
397 }
398
399 pub fn x2(&self) -> Option<bool> {
401 self.x2
402 }
403}
404
405#[derive(Debug, Clone, Copy, PartialEq, Eq)]
408pub struct SdrrLogicalAddress {
409 addr: u32,
412
413 cs_set: SdrrCsSet,
415}
416
417impl SdrrLogicalAddress {
418 pub fn new(addr: u32, cs_set: SdrrCsSet) -> Self {
420 Self { addr, cs_set }
421 }
422
423 pub fn mangle(&self, info: &SdrrInfo) -> Result<u32, String> {
426 info.mangle_address(self)
427 }
428
429 pub fn addr(&self) -> u32 {
431 self.addr
432 }
433
434 pub fn cs_set(&self) -> &SdrrCsSet {
436 &self.cs_set
437 }
438}
439
440#[derive(Debug, Clone, Copy, PartialEq, Eq)]
441pub enum SdrrAddress {
442 Raw(u32),
444
445 Logical(SdrrLogicalAddress),
448}
449
450impl SdrrAddress {
451 pub fn from_raw(addr: u32) -> Self {
453 Self::Raw(addr)
454 }
455
456 pub fn from_logical(addr: u32, cs_set: &SdrrCsSet) -> Self {
458 Self::Logical(SdrrLogicalAddress::new(addr, *cs_set))
459 }
460}
461
462impl fmt::Display for SdrrAddress {
463 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
464 if f.alternate() {
465 match self {
466 SdrrAddress::Raw(addr) => write!(f, "Raw address: 0x{:04X}", addr),
467 SdrrAddress::Logical(logical) => write!(
468 f,
469 "Logical address: 0x{:04X} (CS1: {}, CS2: {:?}, CS3: {:?}, X1: {:?}, X2: {:?})",
470 logical.addr,
471 logical.cs_set.cs1(),
472 logical.cs_set.cs2(),
473 logical.cs_set.cs3(),
474 logical.cs_set.x1(),
475 logical.cs_set.x2()
476 ),
477 }
478 } else {
479 match self {
480 SdrrAddress::Raw(addr) => write!(f, "0x{:04X}", addr),
481 SdrrAddress::Logical(logical) => write!(f, "0x{:04X}", logical.addr),
482 }
483 }
484 }
485}