1use std::{fmt::Display, ops::Range};
5
6use convert_case::Boundary;
7
8pub mod lir_transform;
9pub mod passes;
10
11#[derive(Debug, Clone, PartialEq, Eq, Default)]
12pub struct Device {
13 pub name: Option<String>,
14 pub global_config: GlobalConfig,
15 pub objects: Vec<Object>,
16}
17
18#[derive(Debug, Clone, PartialEq, Eq)]
19pub struct GlobalConfig {
20 pub default_register_access: Access,
21 pub default_field_access: Access,
22 pub default_buffer_access: Access,
23 pub default_byte_order: Option<ByteOrder>,
24 pub default_bit_order: BitOrder,
25 pub register_address_type: Option<Integer>,
26 pub command_address_type: Option<Integer>,
27 pub buffer_address_type: Option<Integer>,
28 pub name_word_boundaries: Vec<Boundary>,
29 pub defmt_feature: Option<String>,
30}
31
32impl Default for GlobalConfig {
33 fn default() -> Self {
34 Self {
35 default_register_access: Default::default(),
36 default_field_access: Default::default(),
37 default_buffer_access: Default::default(),
38 default_byte_order: Default::default(),
39 default_bit_order: Default::default(),
40 register_address_type: Default::default(),
41 command_address_type: Default::default(),
42 buffer_address_type: Default::default(),
43 name_word_boundaries: convert_case::Boundary::defaults(),
44 defmt_feature: Default::default(),
45 }
46 }
47}
48
49#[derive(Debug, Clone, Copy, PartialEq, Eq)]
50pub enum Integer {
51 U8,
52 U16,
53 U32,
54 I8,
55 I16,
56 I32,
57 I64,
58}
59
60impl Integer {
61 pub fn min_value(&self) -> i64 {
62 match self {
63 Integer::U8 => u8::MIN as i64,
64 Integer::U16 => u16::MIN as i64,
65 Integer::U32 => u32::MIN as i64,
66 Integer::I8 => i8::MIN as i64,
67 Integer::I16 => i16::MIN as i64,
68 Integer::I32 => i32::MIN as i64,
69 Integer::I64 => i64::MIN,
70 }
71 }
72
73 pub fn max_value(&self) -> i64 {
74 match self {
75 Integer::U8 => u8::MAX as i64,
76 Integer::U16 => u16::MAX as i64,
77 Integer::U32 => u32::MAX as i64,
78 Integer::I8 => i8::MAX as i64,
79 Integer::I16 => i16::MAX as i64,
80 Integer::I32 => i32::MAX as i64,
81 Integer::I64 => i64::MAX,
82 }
83 }
84}
85
86impl Display for Integer {
87 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88 match self {
89 Integer::U8 => write!(f, "u8"),
90 Integer::U16 => write!(f, "u16"),
91 Integer::U32 => write!(f, "u32"),
92 Integer::I8 => write!(f, "i8"),
93 Integer::I16 => write!(f, "i16"),
94 Integer::I32 => write!(f, "i32"),
95 Integer::I64 => write!(f, "i64"),
96 }
97 }
98}
99
100#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
101pub enum Access {
102 #[default]
103 RW,
104 RO,
105 WO,
106}
107
108impl Access {
109 pub fn is_readable(&self) -> bool {
110 match self {
111 Access::RW => true,
112 Access::RO => true,
113 Access::WO => false,
114 }
115 }
116}
117
118impl Display for Access {
119 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
120 write!(f, "{self:?}")
121 }
122}
123
124#[derive(Debug, Clone, Copy, PartialEq, Eq)]
125pub enum ByteOrder {
126 LE,
127 BE,
128}
129
130impl Display for ByteOrder {
131 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
132 write!(f, "{self:?}")
133 }
134}
135
136#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
137pub enum BitOrder {
138 #[default]
139 LSB0,
140 MSB0,
141}
142
143impl Display for BitOrder {
144 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
145 write!(f, "{self:?}")
146 }
147}
148
149#[derive(Debug, Clone, PartialEq, Eq)]
150pub enum Object {
151 Block(Block),
152 Register(Register),
153 Command(Command),
154 Buffer(Buffer),
155 Ref(RefObject),
156}
157
158impl Object {
159 pub(self) fn get_block_object_list_mut(&mut self) -> Option<&mut Vec<Self>> {
160 match self {
161 Object::Block(b) => Some(&mut b.objects),
162 _ => None,
163 }
164 }
165
166 pub(self) fn get_block_object_list(&self) -> Option<&[Self]> {
167 match self {
168 Object::Block(b) => Some(&b.objects),
169 _ => None,
170 }
171 }
172
173 pub(self) fn name_mut(&mut self) -> &mut String {
175 match self {
176 Object::Block(val) => &mut val.name,
177 Object::Register(val) => &mut val.name,
178 Object::Command(val) => &mut val.name,
179 Object::Buffer(val) => &mut val.name,
180 Object::Ref(val) => &mut val.name,
181 }
182 }
183
184 pub(self) fn name(&self) -> &str {
186 match self {
187 Object::Block(val) => &val.name,
188 Object::Register(val) => &val.name,
189 Object::Command(val) => &val.name,
190 Object::Buffer(val) => &val.name,
191 Object::Ref(val) => &val.name,
192 }
193 }
194
195 pub(self) fn cfg_attr_mut(&mut self) -> &mut Cfg {
197 match self {
198 Object::Block(val) => &mut val.cfg_attr,
199 Object::Register(val) => &mut val.cfg_attr,
200 Object::Command(val) => &mut val.cfg_attr,
201 Object::Buffer(val) => &mut val.cfg_attr,
202 Object::Ref(val) => &mut val.cfg_attr,
203 }
204 }
205
206 pub(self) fn field_sets_mut(&mut self) -> impl Iterator<Item = &mut [Field]> {
208 match self {
209 Object::Register(val) => vec![val.fields.as_mut_slice()].into_iter(),
210 Object::Command(val) => {
211 vec![val.in_fields.as_mut_slice(), val.out_fields.as_mut_slice()].into_iter()
212 }
213 Object::Block(_) | Object::Buffer(_) | Object::Ref(_) => Vec::new().into_iter(),
214 }
215 }
216
217 pub(self) fn field_sets(&self) -> impl Iterator<Item = &[Field]> {
219 match self {
220 Object::Register(val) => vec![val.fields.as_slice()].into_iter(),
221 Object::Command(val) => {
222 vec![val.in_fields.as_slice(), val.out_fields.as_slice()].into_iter()
223 }
224 Object::Block(_) | Object::Buffer(_) | Object::Ref(_) => Vec::new().into_iter(),
225 }
226 }
227
228 pub fn as_block_mut(&mut self) -> Option<&mut Block> {
229 if let Self::Block(v) = self {
230 Some(v)
231 } else {
232 None
233 }
234 }
235
236 pub fn as_register_mut(&mut self) -> Option<&mut Register> {
237 if let Self::Register(v) = self {
238 Some(v)
239 } else {
240 None
241 }
242 }
243
244 pub fn as_register(&self) -> Option<&Register> {
245 if let Self::Register(v) = self {
246 Some(v)
247 } else {
248 None
249 }
250 }
251
252 pub fn as_command_mut(&mut self) -> Option<&mut Command> {
253 if let Self::Command(v) = self {
254 Some(v)
255 } else {
256 None
257 }
258 }
259
260 fn address(&self) -> Option<i64> {
263 match self {
264 Object::Block(block) => Some(block.address_offset),
265 Object::Register(register) => Some(register.address),
266 Object::Command(command) => Some(command.address),
267 Object::Buffer(buffer) => Some(buffer.address),
268 Object::Ref(ref_object) => match &ref_object.object_override {
269 ObjectOverride::Block(block_override) => block_override.address_offset,
270 ObjectOverride::Register(register_override) => register_override.address,
271 ObjectOverride::Command(command_override) => command_override.address,
272 },
273 }
274 }
275
276 fn repeat(&self) -> Option<Repeat> {
278 match self {
279 Object::Block(block) => block.repeat,
280 Object::Register(register) => register.repeat,
281 Object::Command(command) => command.repeat,
282 Object::Buffer(_) => None,
283 Object::Ref(ref_object) => match &ref_object.object_override {
284 ObjectOverride::Block(block_override) => block_override.repeat,
285 ObjectOverride::Register(register_override) => register_override.repeat,
286 ObjectOverride::Command(command_override) => command_override.repeat,
287 },
288 }
289 }
290
291 pub fn as_ref_object_mut(&mut self) -> Option<&mut RefObject> {
292 if let Self::Ref(v) = self {
293 Some(v)
294 } else {
295 None
296 }
297 }
298}
299
300#[derive(Debug, Clone, PartialEq, Eq, Default)]
301pub struct Block {
302 pub cfg_attr: Cfg,
303 pub description: String,
304 pub name: String,
305 pub address_offset: i64,
306 pub repeat: Option<Repeat>,
307 pub objects: Vec<Object>,
308}
309
310#[derive(Debug, Copy, Clone, PartialEq, Eq)]
311pub struct Repeat {
312 pub count: u64,
313 pub stride: i64,
314}
315
316#[derive(Debug, Clone, PartialEq, Eq, Default)]
317pub struct Register {
318 pub cfg_attr: Cfg,
319 pub description: String,
320 pub name: String,
321 pub access: Access,
322 pub byte_order: Option<ByteOrder>,
323 pub bit_order: BitOrder,
324 pub allow_bit_overlap: bool,
325 pub allow_address_overlap: bool,
326 pub address: i64,
327 pub size_bits: u32,
328 pub reset_value: Option<ResetValue>,
329 pub repeat: Option<Repeat>,
330 pub fields: Vec<Field>,
331}
332
333#[derive(Debug, Clone, PartialEq, Eq, Default)]
334pub struct Field {
335 pub cfg_attr: Cfg,
336 pub description: String,
337 pub name: String,
338 pub access: Access,
339 pub base_type: BaseType,
340 pub field_conversion: Option<FieldConversion>,
341 pub field_address: Range<u32>,
342}
343
344#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
345pub enum BaseType {
346 Unspecified,
347 Bool,
348 #[default]
349 Uint,
350 Int,
351 FixedSize(Integer),
352}
353
354#[derive(Debug, Clone, PartialEq, Eq)]
355pub enum FieldConversion {
356 Direct { type_name: String, use_try: bool },
357 Enum { enum_value: Enum, use_try: bool },
358}
359
360impl FieldConversion {
361 pub const fn use_try(&self) -> bool {
362 match self {
363 FieldConversion::Direct { use_try, .. } => *use_try,
364 FieldConversion::Enum { use_try, .. } => *use_try,
365 }
366 }
367
368 pub fn type_name(&self) -> &str {
369 match self {
370 FieldConversion::Direct { type_name, .. } => type_name,
371 FieldConversion::Enum { enum_value, .. } => &enum_value.name,
372 }
373 }
374}
375
376#[derive(Debug, Clone, PartialEq, Eq, Default)]
377pub struct Enum {
378 pub cfg_attr: Cfg,
379 pub description: String,
380 pub name: String,
381 pub variants: Vec<EnumVariant>,
382 generation_style: Option<EnumGenerationStyle>,
383}
384
385impl Enum {
386 pub fn new(description: String, name: String, variants: Vec<EnumVariant>) -> Self {
387 Self {
388 cfg_attr: Cfg::default(),
389 description,
390 name,
391 variants,
392 generation_style: None,
393 }
394 }
395
396 #[cfg(test)]
397 pub fn new_with_style(
398 description: String,
399 name: String,
400 variants: Vec<EnumVariant>,
401 generation_style: EnumGenerationStyle,
402 ) -> Self {
403 Self {
404 cfg_attr: Cfg::default(),
405 description,
406 name,
407 variants,
408 generation_style: Some(generation_style),
409 }
410 }
411}
412
413#[derive(Debug, Clone, PartialEq, Eq)]
414pub enum EnumGenerationStyle {
415 Fallible,
416 Infallible { bit_size: u32 },
417}
418
419impl EnumGenerationStyle {
420 #[must_use]
424 pub fn is_fallible(&self) -> bool {
425 matches!(self, Self::Fallible)
426 }
427}
428
429#[derive(Debug, Clone, PartialEq, Eq, Default)]
430pub struct EnumVariant {
431 pub cfg_attr: Cfg,
432 pub description: String,
433 pub name: String,
434 pub value: EnumValue,
435}
436
437#[derive(Debug, Clone, PartialEq, Eq, Default)]
438pub enum EnumValue {
439 #[default]
440 Unspecified,
441 Specified(i128),
442 Default,
443 CatchAll,
444}
445
446impl EnumValue {
447 #[must_use]
451 pub fn is_default(&self) -> bool {
452 matches!(self, Self::Default)
453 }
454
455 #[must_use]
459 pub fn is_catch_all(&self) -> bool {
460 matches!(self, Self::CatchAll)
461 }
462}
463
464#[derive(Debug, Clone, PartialEq, Eq, Default)]
465pub struct Command {
466 pub cfg_attr: Cfg,
467 pub description: String,
468 pub name: String,
469 pub address: i64,
470 pub byte_order: Option<ByteOrder>,
471 pub bit_order: BitOrder,
472 pub allow_bit_overlap: bool,
473 pub allow_address_overlap: bool,
474 pub size_bits_in: u32,
475 pub size_bits_out: u32,
476 pub repeat: Option<Repeat>,
477 pub in_fields: Vec<Field>,
478 pub out_fields: Vec<Field>,
479}
480
481#[derive(Debug, Clone, PartialEq, Eq, Default)]
482pub struct Buffer {
483 pub cfg_attr: Cfg,
484 pub description: String,
485 pub name: String,
486 pub access: Access,
487 pub address: i64,
488}
489
490#[derive(Debug, Clone, PartialEq, Eq, Default)]
491pub struct RefObject {
492 pub cfg_attr: Cfg,
493 pub description: String,
494 pub name: String,
495 pub object_override: ObjectOverride,
496}
497
498#[derive(Debug, Clone, PartialEq, Eq)]
499pub enum ObjectOverride {
500 Block(BlockOverride),
501 Register(RegisterOverride),
502 Command(CommandOverride),
503}
504
505impl Default for ObjectOverride {
506 fn default() -> Self {
507 Self::Register(Default::default())
508 }
509}
510
511impl ObjectOverride {
512 fn name(&self) -> &str {
513 match self {
514 ObjectOverride::Block(v) => &v.name,
515 ObjectOverride::Register(v) => &v.name,
516 ObjectOverride::Command(v) => &v.name,
517 }
518 }
519
520 fn name_mut(&mut self) -> &mut String {
521 match self {
522 ObjectOverride::Block(v) => &mut v.name,
523 ObjectOverride::Register(v) => &mut v.name,
524 ObjectOverride::Command(v) => &mut v.name,
525 }
526 }
527
528 pub fn as_register(&self) -> Option<&RegisterOverride> {
529 if let Self::Register(v) = self {
530 Some(v)
531 } else {
532 None
533 }
534 }
535
536 pub fn as_register_mut(&mut self) -> Option<&mut RegisterOverride> {
537 if let Self::Register(v) = self {
538 Some(v)
539 } else {
540 None
541 }
542 }
543}
544
545#[derive(Debug, Clone, PartialEq, Eq, Default)]
546pub struct BlockOverride {
547 pub name: String,
548 pub address_offset: Option<i64>,
549 pub repeat: Option<Repeat>,
550}
551
552#[derive(Debug, Clone, PartialEq, Eq, Default)]
553pub struct RegisterOverride {
554 pub name: String,
555 pub access: Option<Access>,
556 pub address: Option<i64>,
557 pub allow_address_overlap: bool,
558 pub reset_value: Option<ResetValue>,
559 pub repeat: Option<Repeat>,
560}
561
562#[derive(Debug, Clone, PartialEq, Eq, Default)]
563pub struct CommandOverride {
564 pub name: String,
565 pub address: Option<i64>,
566 pub allow_address_overlap: bool,
567 pub repeat: Option<Repeat>,
568}
569
570#[derive(Debug, Clone, PartialEq, Eq)]
571pub enum ResetValue {
572 Integer(u128),
573 Array(Vec<u8>),
574}
575
576impl ResetValue {
577 pub fn as_array(&self) -> Option<&Vec<u8>> {
578 if let Self::Array(v) = self {
579 Some(v)
580 } else {
581 None
582 }
583 }
584}
585
586#[derive(Debug, Clone, Eq, PartialEq, Default, Hash)]
587pub struct Cfg {
588 value: Option<String>,
589}
590
591impl Cfg {
592 pub fn new(value: Option<&str>) -> Self {
593 Self {
594 value: value.map(|v| v.into()),
595 }
596 }
597
598 #[must_use]
599 pub fn combine(&self, other: &Self) -> Self {
600 match (&self.value, &other.value) {
601 (None, None) => Self { value: None },
602 (None, Some(val)) => Self {
603 value: Some(val.clone()),
604 },
605 (Some(val), None) => Self {
606 value: Some(val.clone()),
607 },
608 (Some(val1), Some(val2)) if val1 == val2 => Self {
609 value: Some(val1.clone()),
610 },
611 (Some(val1), Some(val2)) => Self {
612 value: Some(format!("all({val1}, {val2})")),
613 },
614 }
615 }
616
617 pub fn inner(&self) -> Option<&str> {
618 self.value.as_deref()
619 }
620}
621
622impl Display for Cfg {
623 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
624 if let Some(value) = self.inner() {
625 write!(f, "#[cfg({value})]")?
626 }
627
628 Ok(())
629 }
630}
631
632#[derive(Debug, Clone, Eq, PartialEq, Hash)]
633pub struct UniqueId {
634 object_name: String,
635 object_cfg: Cfg,
636}
637
638impl Display for UniqueId {
639 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
640 match self.object_cfg.inner() {
641 Some(cfg) => write!(f, "{}(cfg=`{}`)", self.object_name, cfg),
642 None => write!(f, "{}", self.object_name),
643 }
644 }
645}
646
647pub trait Unique {
648 fn id(&self) -> UniqueId;
649}
650
651macro_rules! impl_unique {
652 ($t:ty) => {
653 impl Unique for $t {
654 fn id(&self) -> UniqueId {
655 UniqueId {
656 object_name: self.name.clone(),
657 object_cfg: self.cfg_attr.clone(),
658 }
659 }
660 }
661 };
662}
663
664impl_unique!(Register);
665impl_unique!(Command);
666impl_unique!(Buffer);
667impl_unique!(RefObject);
668impl_unique!(Block);
669impl_unique!(Enum);
670impl_unique!(EnumVariant);
671
672impl Unique for Object {
673 fn id(&self) -> UniqueId {
674 match self {
675 Object::Block(val) => val.id(),
676 Object::Register(val) => val.id(),
677 Object::Command(val) => val.id(),
678 Object::Buffer(val) => val.id(),
679 Object::Ref(val) => val.id(),
680 }
681 }
682}