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