1use crate::debug_access::{self, Statement};
4use log::{error, trace, warn};
5use roxmltree::Node;
6use serde::{Deserialize, Serialize};
7use serde_roxmltree::RawNode;
8use std::{collections::HashMap, fmt::Debug};
9
10fn de_uint<'de, D>(d: D) -> Result<u32, D::Error>
12where
13 D: serde::Deserializer<'de>,
14{
15 let s = String::deserialize(d)?;
16 let trimmed = s.trim();
17 trimmed
18 .strip_prefix("0x")
19 .or_else(|| trimmed.strip_prefix("0X"))
20 .map_or_else(
21 || trimmed.parse::<u32>().map_err(serde::de::Error::custom),
22 |hex| u32::from_str_radix(hex, 16).map_err(serde::de::Error::custom),
23 )
24}
25
26fn de_opt_uint<'de, D>(d: D) -> Result<Option<u32>, D::Error>
29where
30 D: serde::Deserializer<'de>,
31{
32 de_uint(d).map(Some)
33}
34
35fn de_opt_bool<'de, D>(d: D) -> Result<Option<bool>, D::Error>
38where
39 D: serde::Deserializer<'de>,
40{
41 let s = String::deserialize(d)?;
42 match s.as_str() {
43 "true" | "1" => Ok(Some(true)),
44 "false" | "0" => Ok(Some(false)),
45 other => Err(serde::de::Error::custom(format!(
46 "expected xs:boolean, got: {other}"
47 ))),
48 }
49}
50
51#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Default)]
53pub enum FamilyParseError {
54 MissingAttribute(String),
56 UnknownElementType(String),
58 MalformedDebugvar(String),
60 #[default]
62 UnimplementedContent,
63}
64
65impl std::fmt::Display for FamilyParseError {
66 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67 match self {
68 Self::MissingAttribute(attr) => write!(f, "missing attribute: {attr}"),
69 Self::UnknownElementType(tag) => write!(f, "unknown element type: {tag}"),
70 Self::MalformedDebugvar(msg) => write!(f, "malformed debugvar: {msg}"),
71 Self::UnimplementedContent => write!(f, "unimplemented content-parse branch"),
72 }
73 }
74}
75
76impl std::error::Error for FamilyParseError {}
77
78impl From<FamilyParseError> for crate::Error {
79 fn from(value: FamilyParseError) -> Self {
80 Self::Family(value)
81 }
82}
83
84#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Default)]
85pub struct Family<'a> {
87 #[serde(rename = "Dfamily")]
88 pub device_family: String,
90
91 #[serde(rename = "Dvendor")]
92 pub vendor: String,
94
95 pub deprecated: Option<String>,
97
98 #[serde(rename = "description", default)]
100 pub description: Vec<String>,
101
102 #[serde(rename = "processor", default)]
104 pub processor: Vec<Processor>,
105
106 #[serde(rename = "compile", default)]
108 pub compile: Vec<Compile>,
109
110 #[serde(rename = "debug", default)]
112 pub debug: Vec<FamilyDebug>,
113
114 pub debugconfig: Option<DebugConfig>,
116
117 #[serde(rename = "debugport", default)]
119 pub debugport: Vec<DebugPort>,
120
121 #[serde(rename = "accessportV1", default)]
123 pub access_port_v1: Vec<AccessPortV1>,
124
125 #[serde(rename = "accessportV2", default)]
127 pub access_port_v2: Vec<AccessPortV2>,
128
129 #[serde(rename = "algorithm", default)]
131 pub algorithm: Vec<Algorithm>,
132
133 #[serde(rename = "flashinfo", default, borrow, skip_serializing)]
135 pub flashinfo_raw: Vec<RawNode<'a>>,
136
137 #[serde(skip_deserializing)]
139 pub flashinfo: Vec<FlashInfo>,
140
141 #[serde(rename = "memory", default)]
143 pub memory: Vec<Memory>,
144
145 #[serde(rename = "trace", default)]
147 pub trace: Vec<Trace>,
148
149 #[serde(rename = "book", default)]
151 pub book: Vec<Book>,
152
153 #[serde(rename = "feature", default)]
155 pub feature: Vec<Feature>,
156
157 #[serde(rename = "environment", default)]
159 pub environment: Vec<FamilyEnvironment>,
160
161 #[serde(rename = "subFamily", default)]
163 pub sub_families: Vec<SubFamily<'a>>,
164
165 #[serde(rename = "device", default)]
167 pub devices: Vec<Device<'a>>,
168
169 #[serde(rename = "debugvars", default, borrow, skip_serializing)]
171 pub debugvars_raw: Vec<RawNode<'a>>,
172
173 #[serde(skip_deserializing)]
175 pub debugvars: Debugvars,
176
177 #[serde(rename = "sequences", default, borrow, skip_serializing)]
179 pub sequences_raw: Vec<RawNode<'a>>,
180
181 #[serde(skip_deserializing)]
183 pub sequences: Sequences<'a>,
184}
185
186#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Default)]
187pub enum TraceSetup {
189 #[serde(rename = "full")]
190 Full,
191 #[serde(rename = "legacy")]
192 #[default]
193 Legacy,
194}
195
196fn de_opt_trace_setup<'de, D>(d: D) -> Result<Option<TraceSetup>, D::Error>
206where
207 D: serde::Deserializer<'de>,
208{
209 let s = String::deserialize(d)?;
210 match s.as_str() {
211 "full" => Ok(Some(TraceSetup::Full)),
212 "legacy" => Ok(Some(TraceSetup::Legacy)),
213 other => Err(serde::de::Error::custom(format!(
214 "expected TraceSetupEnum, got: {other}"
215 ))),
216 }
217}
218
219#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Default)]
220pub struct Debugvars {
222 pub configfile: Option<String>,
224
225 pub version: Option<String>,
227
228 #[serde(rename = "#content")]
229 pub content: String,
231
232 pub parsed_debugvars: Option<HashMap<String, u64>>,
234}
235
236impl Debugvars {
237 fn parse_value_string(value: &str) -> Option<u64> {
239 if let Some(hex_value_str) = value.strip_prefix("0x")
241 && let Ok(k) = u64::from_str_radix(hex_value_str, 16)
242 {
243 return Some(k);
244 }
245
246 match value.parse() {
248 Ok(k) => Some(k),
249 Err(e) => {
250 error!("Failed to parse debugvar value ({value}) to u64 with error: {e}");
251 None
252 }
253 }
254 }
255
256 pub fn parse_single_debugvar(line: &str) -> Result<(String, u64), FamilyParseError> {
264 trace!("Parsing debugvar line: {line}");
265
266 let declaration = if line.trim_start().starts_with("//") {
268 let parts: Vec<&str> = line.split('\n').collect();
269 match parts.get(1) {
270 Some(v) => v.trim(),
271 None => {
272 return Err(FamilyParseError::MalformedDebugvar(
273 "Unable to get comment body".to_string(),
274 ));
275 }
276 }
277 } else {
278 line.trim()
279 };
280
281 if declaration.is_empty() {
282 return Err(FamilyParseError::MalformedDebugvar(
283 "empty declaration".to_string(),
284 ));
285 }
286
287 let Some(stripped_declaration) = declaration.strip_prefix("__var") else {
288 warn!("Variable in debugvars does not start with \"__var \": {declaration:?}");
289 return Err(FamilyParseError::MalformedDebugvar(format!(
290 "missing '__var' prefix: {declaration:?}"
291 )));
292 };
293
294 let parts: Vec<&str> = stripped_declaration.split('=').collect();
295 if parts.len() != 2 {
296 warn!("Got something other than 2 fields when parsing debugvar: {parts:?}");
297 return Err(FamilyParseError::MalformedDebugvar(format!(
298 "expected exactly one '=' separator, got {} fields",
299 parts.len()
300 )));
301 }
302
303 let name: String = if let Some(v) = parts.first() {
304 v.trim().to_string()
305 } else {
306 return Err(FamilyParseError::MalformedDebugvar(
307 "Unable to variable name in declaration".to_string(),
308 ));
309 };
310 let value_str = if let Some(v) = parts.get(1) {
311 v.trim()
312 } else {
313 return Err(FamilyParseError::MalformedDebugvar(
314 "Unable to variable value in declaration".to_string(),
315 ));
316 };
317
318 Self::parse_value_string(value_str).map_or_else(
319 || {
320 Err(FamilyParseError::MalformedDebugvar(format!(
321 "could not parse value as u64: {value_str:?}"
322 )))
323 },
324 |value| Ok((name, value)),
325 )
326 }
327
328 #[must_use]
330 pub fn parse_debugvars_content(&self) -> HashMap<String, u64> {
331 let content: String = self
333 .content
334 .split('\n')
335 .filter_map(|line| {
336 if line.trim().starts_with("//") {
337 trace!("Ignoring line: {line}");
338 None
339 } else {
340 Some(line.to_owned() + "\n") }
342 })
343 .collect();
344
345 let variables: Vec<&str> = content.split(';').collect();
350
351 variables
352 .iter()
353 .filter_map(|var| {
354 Self::parse_single_debugvar(var).ok()
356 })
357 .collect()
358 }
359
360 pub fn parse_debugvars(&mut self) {
362 let vars = self.parse_debugvars_content();
363
364 self.parsed_debugvars = Some(vars);
365 }
366}
367
368pub fn merge_debugvars(raw_nodes: &[RawNode<'_>]) -> Result<Debugvars, crate::Error> {
382 let mut merged = Debugvars::default();
383 let mut contents: Vec<String> = Vec::new();
384
385 for node in raw_nodes {
386 let parsed: Debugvars = serde_roxmltree::from_node(node.0)?;
387
388 if merged.configfile.is_none() {
389 merged.configfile = parsed.configfile;
390 }
391 if merged.version.is_none() {
392 merged.version = parsed.version;
393 }
394 if !parsed.content.is_empty() {
395 contents.push(parsed.content);
396 }
397 }
398
399 merged.content = contents.join("\n");
400
401 Ok(merged)
402}
403
404#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
406pub struct Processor {
407 #[serde(rename = "Pname")]
409 pub pname: Option<String>,
410 #[serde(rename = "Punits")]
412 pub punits: Option<u32>,
413 #[serde(rename = "Dcore")]
415 pub dcore: Option<String>,
416 #[serde(rename = "DcoreVersion")]
418 pub dcore_version: Option<String>,
419 #[serde(rename = "Dfpu")]
421 pub dfpu: Option<String>,
422 #[serde(rename = "Dmpu")]
424 pub dmpu: Option<String>,
425 #[serde(rename = "Ddsp")]
427 pub ddsp: Option<String>,
428 #[serde(rename = "Dmve")]
430 pub dmve: Option<String>,
431 #[serde(rename = "Dpacbti")]
433 pub dpacbti: Option<String>,
434 #[serde(rename = "Dtz")]
436 pub dtz: Option<String>,
437 #[serde(rename = "Dendian")]
439 pub dendian: Option<String>,
440 #[serde(rename = "Dclock")]
442 pub dclock: Option<u64>,
443}
444
445#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
447pub struct Compile {
448 #[serde(rename = "Pname")]
450 pub pname: Option<String>,
451 pub header: Option<String>,
453 pub define: Option<String>,
455 #[serde(rename = "Pdefine")]
457 pub pdefine: Option<String>,
458}
459
460#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
462pub struct FamilyDebug {
463 #[serde(rename = "Pname")]
465 pub pname: Option<String>,
466 #[serde(rename = "Punit")]
468 pub punit: Option<u32>,
469 pub svd: Option<String>,
471 #[serde(rename = "__dp")]
473 pub dp: Option<u32>,
474 #[serde(rename = "__ap")]
476 pub ap: Option<u32>,
477 #[serde(rename = "__apid")]
479 pub apid: Option<u32>,
480 pub address: Option<String>,
482 #[serde(rename = "defaultResetSequence")]
484 pub default_reset_sequence: Option<String>,
485 #[serde(rename = "datapatch", default)]
487 pub datapatch: Vec<DataPatch>,
488}
489
490#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
492pub struct DataPatch {
493 #[serde(rename = "type")]
495 pub patch_type: Option<String>,
496 #[serde(deserialize_with = "de_uint")]
498 pub address: u32,
499 #[serde(rename = "__dp")]
501 pub dp: Option<u32>,
502 #[serde(rename = "__ap")]
504 pub ap: Option<u32>,
505 #[serde(deserialize_with = "de_uint")]
507 pub value: u32,
508 pub mask: Option<String>,
510 pub info: Option<String>,
512 #[serde(rename = "__apid")]
514 pub apid: Option<u32>,
515}
516
517#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
519pub struct DebugConfig {
520 pub default: Option<String>,
522 pub clock: Option<u64>,
524 #[serde(default, deserialize_with = "de_opt_bool")]
526 pub swj: Option<bool>,
527 #[serde(default, deserialize_with = "de_opt_bool")]
529 pub dormant: Option<bool>,
530 pub sdf: Option<String>,
532}
533
534#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
536pub struct DebugPort {
537 #[serde(rename = "__dp")]
539 pub dp: Option<u32>,
540 pub jtag: Option<DebugPortJtag>,
542 pub swd: Option<DebugPortSwd>,
544}
545
546#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
548pub struct DebugPortJtag {
549 #[serde(rename = "tapindex", default, deserialize_with = "de_opt_uint")]
551 pub tapindex: Option<u32>,
552 #[serde(default, deserialize_with = "de_opt_uint")]
554 pub idcode: Option<u32>,
555 #[serde(default, deserialize_with = "de_opt_uint")]
557 pub targetsel: Option<u32>,
558 pub irlen: Option<u32>,
560}
561
562#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
564pub struct DebugPortSwd {
565 #[serde(default, deserialize_with = "de_opt_uint")]
567 pub idcode: Option<u32>,
568 #[serde(default, deserialize_with = "de_opt_uint")]
570 pub targetsel: Option<u32>,
571}
572
573#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
575pub struct AccessPortV1 {
576 #[serde(rename = "__apid")]
578 pub apid: u32,
579 #[serde(rename = "__dp")]
581 pub dp: Option<u32>,
582 pub index: u32,
584 #[serde(rename = "HPROT")]
586 pub hprot: Option<u32>,
587 #[serde(rename = "SPROT")]
589 pub sprot: Option<u32>,
590}
591
592#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
594pub struct AccessPortV2 {
595 #[serde(rename = "__apid")]
597 pub apid: u32,
598 #[serde(rename = "__dp")]
600 pub dp: Option<u32>,
601 pub address: String,
603 #[serde(rename = "HPROT")]
605 pub hprot: Option<u32>,
606 #[serde(rename = "SPROT")]
608 pub sprot: Option<u32>,
609 pub parent: Option<u32>,
611}
612
613fn default_algorithm_endian() -> String {
615 "Little-endian".to_string()
616}
617
618#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
620pub struct Algorithm {
621 pub name: String,
623 pub start: Option<String>,
625 pub size: Option<String>,
627 #[serde(rename = "RAMstart")]
629 pub ram_start: Option<String>,
630 #[serde(rename = "RAMsize")]
632 pub ram_size: Option<String>,
633 #[serde(default, deserialize_with = "de_opt_bool")]
635 pub default: Option<bool>,
636 pub style: Option<String>,
638 #[serde(rename = "Pname")]
640 pub pname: Option<String>,
641 #[serde(rename = "deviceIndex")]
643 pub device_index: Option<String>,
644 pub parameter: Option<String>,
646 #[serde(default = "default_algorithm_endian")]
648 pub endian: String,
649}
650
651#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
653pub struct FlashInfo {
654 pub name: String,
656 pub start: String,
658 pub pagesize: String,
660 pub blankval: Option<String>,
662 pub filler: Option<String>,
664 pub ptime: Option<u32>,
666 pub etime: Option<u32>,
668 #[serde(rename = "Pname")]
670 pub pname: Option<String>,
671 #[serde(skip_deserializing)]
677 pub elements: Vec<FlashInfoElement>,
678}
679
680impl<'a, 'input: 'a> TryFrom<Node<'a, 'input>> for FlashInfo {
681 type Error = crate::Error;
682
683 fn try_from(value: Node<'a, 'input>) -> Result<Self, Self::Error> {
684 let mut info: Self = serde_roxmltree::from_node(value)?;
685
686 for child in value.children().filter(roxmltree::Node::is_element) {
687 info.elements.push(child.try_into()?);
688 }
689
690 Ok(info)
691 }
692}
693
694pub fn parse_flashinfo(raw_nodes: &[RawNode<'_>]) -> Result<Vec<FlashInfo>, crate::Error> {
700 raw_nodes
701 .iter()
702 .map(|node| {
703 node.0.try_into().inspect_err(|e| {
704 error!("Failed to parse flashinfo node `{node:#?}` with err `{e:#?}`");
705 })
706 })
707 .collect()
708}
709
710#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
712pub struct FlashBlock {
713 #[serde(deserialize_with = "de_uint")]
715 pub count: u32,
716 pub size: String,
718 pub arg: Option<String>,
720}
721
722#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
724pub struct FlashGap {
725 pub size: String,
727}
728
729#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
731pub enum FlashInfoElement {
732 Block(FlashBlock),
734 Gap(FlashGap),
736}
737
738impl Default for FlashInfoElement {
739 fn default() -> Self {
740 Self::Block(FlashBlock::default())
741 }
742}
743
744impl<'a, 'input: 'a> TryFrom<Node<'a, 'input>> for FlashInfoElement {
745 type Error = crate::Error;
746
747 fn try_from(value: Node<'a, 'input>) -> Result<Self, Self::Error> {
748 if !value.is_element() {
749 return Err(FamilyParseError::UnimplementedContent.into());
751 }
752 match value.tag_name().name().to_lowercase().as_str() {
753 "block" => Ok(Self::Block(serde_roxmltree::from_node(value)?)),
754 "gap" => Ok(Self::Gap(serde_roxmltree::from_node(value)?)),
755 other => Err(FamilyParseError::UnknownElementType(other.to_string()).into()),
756 }
757 }
758}
759
760#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
762pub struct Memory {
763 pub name: Option<String>,
765 pub access: Option<String>,
767 pub start: String,
769 pub size: String,
771 #[serde(default, deserialize_with = "de_opt_bool")]
773 pub default: Option<bool>,
774 #[serde(default, deserialize_with = "de_opt_bool")]
776 pub startup: Option<bool>,
777 #[serde(default, deserialize_with = "de_opt_bool")]
779 pub uninit: Option<bool>,
780 pub alias: Option<String>,
782 #[serde(rename = "Pname")]
784 pub pname: Option<String>,
785}
786
787#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
789pub struct Trace {
790 #[serde(rename = "Pname")]
792 pub pname: Option<String>,
793 #[serde(rename = "serialwire", default)]
795 pub serialwire: Vec<SerialWire>,
796 #[serde(rename = "traceport", default)]
798 pub traceport: Vec<TracePort>,
799 #[serde(rename = "tracebuffer", default)]
801 pub tracebuffer: Vec<TraceBuffer>,
802}
803
804#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
808pub struct SerialWire {
809 }
811
812#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
814pub struct TracePort {
815 #[serde(default, deserialize_with = "de_opt_uint")]
817 pub width: Option<u32>,
818}
819
820#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
822pub struct TraceBuffer {
823 pub start: Option<String>,
825 pub size: Option<String>,
827}
828
829#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
831pub struct Book {
832 pub name: String,
834 pub title: String,
836 #[serde(rename = "Pname")]
838 pub pname: Option<String>,
839 #[serde(default, deserialize_with = "de_opt_bool")]
841 pub public: Option<bool>,
842}
843
844#[allow(clippy::too_long_first_doc_paragraph)]
845#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
848pub struct Feature {
849 #[serde(rename = "type")]
851 pub feature_type: String,
852 pub n: Option<String>,
854 pub m: Option<String>,
856 pub name: Option<String>,
858 #[serde(rename = "Pname")]
860 pub pname: Option<String>,
861 pub count: Option<i32>,
863}
864
865#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
867pub struct FamilyEnvironment {
868 pub name: String,
870 #[serde(rename = "Pname")]
872 pub pname: Option<String>,
873}
874
875#[derive(Debug, PartialEq, Eq, Clone, Default, Deserialize, Serialize)]
879pub struct Variant<'a> {
880 #[serde(rename = "Dvariant")]
882 pub variant_name: String,
883 pub deprecated: Option<String>,
885 #[serde(rename = "description", default)]
887 pub description: Vec<String>,
888 #[serde(rename = "processor", default)]
890 pub processor: Vec<Processor>,
891 #[serde(rename = "compile", default)]
893 pub compile: Vec<Compile>,
894 #[serde(rename = "debug", default)]
896 pub debug: Vec<FamilyDebug>,
897 pub debugconfig: Option<DebugConfig>,
899 #[serde(rename = "debugport", default)]
901 pub debugport: Vec<DebugPort>,
902 #[serde(rename = "accessportV1", default)]
904 pub access_port_v1: Vec<AccessPortV1>,
905 #[serde(rename = "accessportV2", default)]
907 pub access_port_v2: Vec<AccessPortV2>,
908 #[serde(rename = "algorithm", default)]
910 pub algorithm: Vec<Algorithm>,
911 #[serde(rename = "flashinfo", default, borrow, skip_serializing)]
913 pub flashinfo_raw: Vec<RawNode<'a>>,
914
915 #[serde(skip_deserializing)]
917 pub flashinfo: Vec<FlashInfo>,
918 #[serde(rename = "memory", default)]
920 pub memory: Vec<Memory>,
921 #[serde(rename = "trace", default)]
923 pub trace: Vec<Trace>,
924 #[serde(rename = "book", default)]
926 pub book: Vec<Book>,
927 #[serde(rename = "feature", default)]
929 pub feature: Vec<Feature>,
930 #[serde(rename = "environment", default)]
932 pub environment: Vec<FamilyEnvironment>,
933 #[serde(rename = "debugvars", default, borrow, skip_serializing)]
935 pub debugvars_raw: Vec<RawNode<'a>>,
936 #[serde(skip_deserializing)]
939 pub debugvars: Debugvars,
940 #[serde(rename = "sequences", default, borrow, skip_serializing)]
942 pub sequences_raw: Vec<RawNode<'a>>,
943 #[serde(skip_deserializing)]
946 pub sequences: Sequences<'a>,
947}
948
949#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Default)]
951pub struct Device<'a> {
952 #[serde(rename = "Dname")]
954 pub device_name: String,
955 pub deprecated: Option<String>,
957 #[serde(rename = "description", default)]
959 pub description: Vec<String>,
960 #[serde(rename = "processor", default)]
962 pub processor: Vec<Processor>,
963 #[serde(rename = "compile", default)]
965 pub compile: Vec<Compile>,
966 #[serde(rename = "debug", default)]
968 pub debug: Vec<FamilyDebug>,
969 pub debugconfig: Option<DebugConfig>,
971 #[serde(rename = "debugport", default)]
973 pub debugport: Vec<DebugPort>,
974 #[serde(rename = "accessportV1", default)]
976 pub access_port_v1: Vec<AccessPortV1>,
977 #[serde(rename = "accessportV2", default)]
979 pub access_port_v2: Vec<AccessPortV2>,
980 #[serde(rename = "algorithm", default)]
982 pub algorithm: Vec<Algorithm>,
983 #[serde(rename = "flashinfo", default, borrow, skip_serializing)]
985 pub flashinfo_raw: Vec<RawNode<'a>>,
986
987 #[serde(skip_deserializing)]
989 pub flashinfo: Vec<FlashInfo>,
990 #[serde(rename = "memory", default)]
992 pub memory: Vec<Memory>,
993 #[serde(rename = "trace", default)]
995 pub trace: Vec<Trace>,
996 #[serde(rename = "book", default)]
998 pub book: Vec<Book>,
999 #[serde(rename = "feature", default)]
1001 pub feature: Vec<Feature>,
1002 #[serde(rename = "environment", default)]
1004 pub environment: Vec<FamilyEnvironment>,
1005 #[serde(rename = "debugvars", default, borrow, skip_serializing)]
1007 pub debugvars_raw: Vec<RawNode<'a>>,
1008 #[serde(skip_deserializing)]
1011 pub debugvars: Debugvars,
1012 #[serde(rename = "sequences", default, borrow, skip_serializing)]
1014 pub sequences_raw: Vec<RawNode<'a>>,
1015 #[serde(skip_deserializing)]
1018 pub sequences: Sequences<'a>,
1019 #[serde(rename = "variant", default)]
1021 pub variants: Vec<Variant<'a>>,
1022}
1023
1024#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Default)]
1026pub struct SubFamily<'a> {
1027 #[serde(rename = "DsubFamily")]
1029 pub sub_family_name: String,
1030 pub deprecated: Option<String>,
1032 #[serde(rename = "description", default)]
1034 pub description: Vec<String>,
1035 #[serde(rename = "processor", default)]
1037 pub processor: Vec<Processor>,
1038 #[serde(rename = "compile", default)]
1040 pub compile: Vec<Compile>,
1041 #[serde(rename = "debug", default)]
1043 pub debug: Vec<FamilyDebug>,
1044 pub debugconfig: Option<DebugConfig>,
1046 #[serde(rename = "debugport", default)]
1048 pub debugport: Vec<DebugPort>,
1049 #[serde(rename = "accessportV1", default)]
1051 pub access_port_v1: Vec<AccessPortV1>,
1052 #[serde(rename = "accessportV2", default)]
1054 pub access_port_v2: Vec<AccessPortV2>,
1055 #[serde(rename = "algorithm", default)]
1057 pub algorithm: Vec<Algorithm>,
1058 #[serde(rename = "flashinfo", default, borrow, skip_serializing)]
1060 pub flashinfo_raw: Vec<RawNode<'a>>,
1061
1062 #[serde(skip_deserializing)]
1064 pub flashinfo: Vec<FlashInfo>,
1065 #[serde(rename = "memory", default)]
1067 pub memory: Vec<Memory>,
1068 #[serde(rename = "trace", default)]
1070 pub trace: Vec<Trace>,
1071 #[serde(rename = "book", default)]
1073 pub book: Vec<Book>,
1074 #[serde(rename = "feature", default)]
1076 pub feature: Vec<Feature>,
1077 #[serde(rename = "environment", default)]
1079 pub environment: Vec<FamilyEnvironment>,
1080 #[serde(rename = "debugvars", default, borrow, skip_serializing)]
1082 pub debugvars_raw: Vec<RawNode<'a>>,
1083 #[serde(skip_deserializing)]
1085 pub debugvars: Debugvars,
1086 #[serde(rename = "sequences", default, borrow, skip_serializing)]
1088 pub sequences_raw: Vec<RawNode<'a>>,
1089 #[serde(skip_deserializing)]
1091 pub sequences: Sequences<'a>,
1092 #[serde(rename = "device", default)]
1094 pub devices: Vec<Device<'a>>,
1095}
1096
1097#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Default)]
1098pub struct Sequences<'a> {
1100 #[serde(
1102 rename = "traceSetup",
1103 default,
1104 deserialize_with = "de_opt_trace_setup"
1105 )]
1106 pub trace_setup: Option<TraceSetup>,
1107
1108 #[serde(rename = "sequence", default)]
1114 #[serde(borrow)]
1115 #[serde(skip_serializing)]
1116 pub raw_nodes: Vec<RawNode<'a>>,
1117
1118 #[serde(skip_deserializing)]
1120 pub sequences: Vec<Sequence>,
1121}
1122
1123impl Sequences<'_> {
1124 pub fn parse_raw_nodes_content(&self) -> Result<Vec<Sequence>, crate::Error> {
1130 self.raw_nodes
1131 .iter()
1132 .map(|node| {
1133 node.0.try_into().inspect_err(|e| {
1134 error!("Failed to parse sequence node `{node:#?}` with err `{e:#?}`");
1135 })
1136 })
1137 .collect()
1138 }
1139
1140 pub fn parse_sequences(&mut self) -> Result<(), crate::Error> {
1146 let sequences = Self::parse_raw_nodes_content(self)?;
1147
1148 self.sequences = sequences;
1149
1150 Ok(())
1151 }
1152}
1153
1154pub fn merge_sequences<'a>(raw_nodes: &[RawNode<'a>]) -> Result<Sequences<'a>, crate::Error> {
1167 let mut merged = Sequences::default();
1168
1169 for node in raw_nodes {
1170 let parsed: Sequences<'a> = serde_roxmltree::from_node(node.0)?;
1171
1172 if merged.trace_setup.is_none() {
1173 merged.trace_setup = parsed.trace_setup;
1174 }
1175 merged.raw_nodes.extend(parsed.raw_nodes);
1176 }
1177
1178 Ok(merged)
1179}
1180
1181#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Default)]
1182pub struct Sequence {
1184 pub name: String,
1186
1187 pub processor_name: Option<String>,
1189
1190 pub disable: Option<bool>,
1192
1193 pub info: Option<String>,
1195
1196 #[serde(skip_serializing)]
1197 pub elements: Vec<SequenceElement>,
1198}
1199
1200impl<'a, 'input: 'a> TryFrom<Node<'a, 'input>> for Sequence {
1201 type Error = crate::Error;
1202
1203 fn try_from(value: Node<'a, 'input>) -> Result<Self, Self::Error> {
1204 let node_name = value.tag_name().name();
1206 if node_name != "sequence" {
1207 return Err(FamilyParseError::UnknownElementType(node_name.to_string()).into());
1208 }
1209
1210 let sequence_name = value
1212 .attribute("name")
1213 .ok_or_else(|| FamilyParseError::MissingAttribute("name".to_string()))?;
1214
1215 let sequence_processor_name = value
1217 .attribute("Pname")
1218 .map_or_else(|| None, |v| Some(v.to_string()));
1219 let sequence_disable = {
1220 value.attribute("disable").and_then(|v| {
1221 let disable_value: bool = match v.parse() {
1222 Ok(k) => k,
1223 Err(e) => {
1224 error!("Failed to parse non-boolean value `{v}` with error `{e:#?}`");
1225 return None;
1226 }
1227 };
1228 Some(disable_value)
1229 })
1230 };
1231 let sequence_info = value
1232 .attribute("info")
1233 .map_or_else(|| None, |v| Some(v.to_string()));
1234
1235 let mut elements: Vec<SequenceElement> = Vec::new();
1237
1238 for child in value.children().filter(roxmltree::Node::is_element) {
1240 let element: SequenceElement = child.try_into()?;
1241
1242 elements.push(element);
1243 }
1244
1245 Ok(Self {
1246 name: sequence_name.to_string(),
1247 processor_name: sequence_processor_name,
1248 disable: sequence_disable,
1249 info: sequence_info,
1250 elements,
1251 })
1252 }
1253}
1254
1255impl<'a, 'input: 'a> TryFrom<Node<'a, 'input>> for SequenceElement {
1256 type Error = crate::Error;
1257
1258 fn try_from(value: Node<'a, 'input>) -> Result<Self, Self::Error> {
1259 if !value.is_element() {
1260 return Err(FamilyParseError::UnimplementedContent.into());
1262 }
1263 match value.tag_name().name().to_lowercase().as_str() {
1264 "block" => Ok(<Node<'_, '_> as TryInto<SequenceBlock>>::try_into(value)?.into()),
1265 "control" => Ok(<Node<'_, '_> as TryInto<SequenceControl>>::try_into(value)?.into()),
1266 other => Err(FamilyParseError::UnknownElementType(other.to_string()).into()),
1267 }
1268 }
1269}
1270
1271impl<'a, 'input: 'a> TryFrom<Node<'a, 'input>> for SequenceBlock {
1272 type Error = crate::Error;
1273
1274 fn try_from(value: Node<'a, 'input>) -> Result<Self, Self::Error> {
1275 let mut block: Self = serde_roxmltree::from_node(value)?;
1276 block.parse_statements()?;
1277 Ok(block)
1278 }
1279}
1280
1281impl<'a, 'input: 'a> TryFrom<Node<'a, 'input>> for SequenceControl {
1282 type Error = crate::Error;
1283
1284 fn try_from(value: Node<'a, 'input>) -> Result<Self, Self::Error> {
1285 let mut block: Self = serde_roxmltree::from_node(value)?;
1287
1288 for child in value.children().filter(roxmltree::Node::is_element) {
1290 let element: SequenceElement = child.try_into()?;
1291
1292 block.elements.push(element);
1293 }
1294
1295 let conditional_string: &str;
1297 if let Some(ref val) = block.conditional_if {
1298 conditional_string = val.as_str();
1299 } else if let Some(ref val) = block.conditional_while {
1300 conditional_string = val.as_str();
1301 } else {
1302 return Err(FamilyParseError::MissingAttribute(
1303 "conditional 'if' or 'while' attribute".to_string(),
1304 )
1305 .into());
1306 }
1307
1308 let conditional: debug_access::Expression = conditional_string.try_into()?;
1309 block.conditional = Some(conditional);
1310
1311 Ok(block)
1312 }
1313}
1314
1315#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
1316pub enum SequenceElement {
1318 Control(SequenceControl),
1320 Block(SequenceBlock),
1322}
1323
1324impl Default for SequenceElement {
1325 fn default() -> Self {
1326 Self::Block(SequenceBlock::default())
1327 }
1328}
1329
1330#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Default)]
1331pub struct SequenceControl {
1333 #[serde(rename = "if")]
1335 pub conditional_if: Option<String>,
1336
1337 #[serde(rename = "while")]
1339 pub conditional_while: Option<String>,
1340
1341 pub timeout: Option<u64>,
1343
1344 pub info: Option<String>,
1346
1347 #[serde(skip_deserializing)]
1348 pub elements: Vec<SequenceElement>,
1350
1351 #[serde(skip_deserializing)]
1352 pub conditional: Option<debug_access::Expression>,
1358}
1359
1360impl From<SequenceControl> for SequenceElement {
1361 fn from(value: SequenceControl) -> Self {
1362 Self::Control(value)
1363 }
1364}
1365
1366#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Default)]
1367pub struct SequenceBlock {
1369 pub atomic: Option<bool>,
1371
1372 pub info: Option<String>,
1374
1375 #[serde(rename = "#content")]
1376 pub content: String,
1378
1379 #[serde(skip_deserializing)]
1380 pub statements: Vec<Statement>,
1382}
1383
1384impl SequenceBlock {
1385 pub fn parse_statements_content(&self) -> Result<Vec<Statement>, crate::Error> {
1391 self.content
1392 .lines()
1393 .flat_map(|line| line.split(';'))
1394 .map(str::trim)
1395 .filter(|s| !s.is_empty())
1396 .map(|s| Statement::try_from(s.to_string()))
1397 .collect()
1398 }
1399
1400 pub fn parse_statements(&mut self) -> Result<(), crate::Error> {
1406 self.statements = self.parse_statements_content()?;
1407
1408 Ok(())
1409 }
1410}
1411
1412impl From<SequenceBlock> for SequenceElement {
1413 fn from(value: SequenceBlock) -> Self {
1414 Self::Block(value)
1415 }
1416}
1417
1418#[cfg(test)]
1419mod tests {
1420 use roxmltree::Document;
1421 use serde_roxmltree::RawNode;
1422
1423 use crate::{
1424 debug_access::{
1425 Assignment, DebugFunction, Expression,
1426 Statement::{self},
1427 },
1428 family::{
1429 FamilyParseError, FlashBlock, FlashGap, FlashInfoElement, Sequence, SequenceBlock,
1430 SequenceControl, SequenceElement, TraceSetup, parse_flashinfo,
1431 },
1432 };
1433
1434 #[test]
1435 fn basic_sequence() {
1436 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
1437<sequence name="ResetSystem">
1438 <block>
1439 Sequence("ResetAndHalt");
1440 </block>
1441</sequence>"#;
1442
1443 let document = Document::parse(xml_str).unwrap();
1444 let sequence_node = document.root_element();
1445 let raw_node: RawNode = RawNode(sequence_node);
1446
1447 let sequence: Sequence = raw_node.0.try_into().unwrap();
1448
1449 assert_eq!(sequence.name, "ResetSystem".to_string());
1450 assert_eq!(
1451 sequence.elements,
1452 vec![
1453 SequenceBlock {
1454 atomic: None,
1455 info: None,
1456 content: "\n Sequence(\"ResetAndHalt\");\n ".to_string(),
1457 statements: vec![Statement::Expression(Expression::FunctionCall(Box::new(
1458 DebugFunction::Sequence {
1459 name: Expression::Normal("\"ResetAndHalt\"".to_string())
1460 }
1461 )))]
1462 }
1463 .into()
1464 ]
1465 );
1466 }
1467
1468 #[test]
1469 fn full_sequence() {
1471 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
1472<sequence name="UserSequence">
1473 <block info="Define variables and do debug accesses">
1474 __var tpWidth = (__traceout & 0x003F0000) >> 16;
1475 </block>
1476
1477 <control if="__traceout & 0x2" info="Parallel Trace Port enabled">
1478 <block>
1479 // Do something generic for parallel trace port trace
1480 </block>
1481
1482 <control if="tpWidth == 1" info="Configure device for 1-bit TPIU trace.">
1483 <block>
1484 // Do debug accesses
1485 </block>
1486 </control>
1487
1488 <control if="tpWidth == 2" info="Configure device for 2-bit TPIU trace.">
1489 <block>
1490 // Do debug accesses
1491 </block>
1492 </control>
1493
1494 <control if="tpWidth == 4" info="Configure device for 4-bit TPIU trace.">
1495 <block>
1496 // Do debug accesses
1497 </block>
1498 </control>
1499 </control>
1500</sequence>"#;
1501
1502 let document = Document::parse(xml_str).unwrap();
1503 let sequence_node = document.root_element();
1504 let raw_node: RawNode = RawNode(sequence_node);
1505
1506 let sequence: Sequence = raw_node.0.try_into().unwrap();
1507
1508 assert_eq!(sequence.name, "UserSequence".to_string());
1510 assert_eq!(sequence.disable, None);
1511 assert_eq!(sequence.info, None);
1512 assert_eq!(sequence.processor_name, None);
1513
1514 let debug_access_block: SequenceElement = SequenceBlock {
1516 atomic: None,
1517 info: None,
1518 content: r#"
1519 // Do debug accesses
1520 "#
1521 .to_string(),
1522 statements: vec![Statement::Comment("// Do debug accesses".to_string())],
1523 }
1524 .into();
1525
1526 let expected_elements: Vec<SequenceElement> = vec![
1528 SequenceBlock {
1529 atomic: None,
1530 info: Some("Define variables and do debug accesses".to_string()),
1531 content: r#"
1532 __var tpWidth = (__traceout & 0x003F0000) >> 16;
1533 "#
1534 .to_string(),
1535 statements: vec![Statement::Definition(Assignment {
1536 variable: "tpWidth".to_string(),
1537 expression: Expression::Normal("(__traceout & 0x003F0000) >> 16".to_string()),
1538 })],
1539 }
1540 .into(),
1541 SequenceControl {
1542 conditional_if: Some("__traceout & 0x2".to_string()),
1543 conditional_while: None,
1544 timeout: None,
1545 info: Some("Parallel Trace Port enabled".to_string()),
1546 elements: vec![
1547 SequenceBlock {
1548 atomic: None,
1549 info: None,
1550 content: r#"
1551 // Do something generic for parallel trace port trace
1552 "#
1553 .to_string(),
1554 statements: vec![Statement::Comment(
1555 "// Do something generic for parallel trace port trace".to_string(),
1556 )],
1557 }
1558 .into(),
1559 SequenceControl {
1560 conditional_if: Some("tpWidth == 1".to_string()),
1561 conditional_while: None,
1562 timeout: None,
1563 info: Some("Configure device for 1-bit TPIU trace.".to_string()),
1564 elements: vec![debug_access_block.clone().into()],
1565 conditional: Some(Expression::Normal("tpWidth == 1".to_string())),
1566 }
1567 .into(),
1568 SequenceControl {
1569 conditional_if: Some("tpWidth == 2".to_string()),
1570 conditional_while: None,
1571 timeout: None,
1572 info: Some("Configure device for 2-bit TPIU trace.".to_string()),
1573 elements: vec![debug_access_block.clone().into()],
1574 conditional: Some(Expression::Normal("tpWidth == 2".to_string())),
1575 }
1576 .into(),
1577 SequenceControl {
1578 conditional_if: Some("tpWidth == 4".to_string()),
1579 conditional_while: None,
1580 timeout: None,
1581 info: Some("Configure device for 4-bit TPIU trace.".to_string()),
1582 elements: vec![debug_access_block.clone().into()],
1583 conditional: Some(Expression::Normal("tpWidth == 4".to_string())),
1584 }
1585 .into(),
1586 ],
1587 conditional: Some(Expression::Normal("__traceout & 0x2".to_string())),
1588 }
1589 .into(),
1590 ];
1591
1592 println!("Expected: {:#?}", expected_elements);
1593 println!("Actual: {:#?}", sequence.elements);
1594
1595 assert_eq!(sequence.elements, expected_elements);
1596 }
1597
1598 #[test]
1599 fn basic_sequence_block() {
1600 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
1601<block info="Define condition variales for later use in block elements.">
1602 // Variable definition by __var keyword
1603 __var doIfBlock = 1;
1604 __var whileCondition = 1;
1605</block>"#;
1606
1607 let document = Document::parse(xml_str).unwrap();
1608 let sequence_node = document.root_element();
1609 let raw_node: RawNode = RawNode(sequence_node);
1610
1611 let block: SequenceBlock = raw_node.0.try_into().unwrap();
1612
1613 assert_eq!(
1614 block.info,
1615 Some("Define condition variales for later use in block elements.".to_string())
1616 );
1617 assert_eq!(block.atomic, None);
1618 assert_eq!(
1619 block.content,
1620 r#"
1621 // Variable definition by __var keyword
1622 __var doIfBlock = 1;
1623 __var whileCondition = 1;
1624"#
1625 );
1626 assert_eq!(
1627 block.statements,
1628 vec![
1629 Statement::Comment("// Variable definition by __var keyword".to_string()),
1630 Statement::Definition(Assignment {
1631 variable: "doIfBlock".to_string(),
1632 expression: Expression::Normal("1".to_string())
1633 }),
1634 Statement::Definition(Assignment {
1635 variable: "whileCondition".to_string(),
1636 expression: Expression::Normal("1".to_string())
1637 })
1638 ]
1639 );
1640 }
1641
1642 #[test]
1643 fn parse_control_element_if() {
1644 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
1645<control if="doIfBlock">
1646 <block>
1647 // Do debug accesses
1648 </block>
1649</control>"#;
1650
1651 let document = Document::parse(xml_str).unwrap();
1652 let sequence_node = document.root_element();
1653 let raw_node: RawNode = RawNode(sequence_node);
1654
1655 let block: SequenceControl = raw_node.0.try_into().unwrap();
1656
1657 println!("{:#?}", block);
1658 assert_eq!(block.info, None);
1659 assert_eq!(block.conditional_if, Some("doIfBlock".to_string()));
1660 assert_eq!(block.conditional_while, None);
1661 assert_eq!(block.timeout, None);
1662 assert_eq!(
1663 block.elements,
1664 vec![
1665 SequenceBlock {
1666 atomic: None,
1667 info: None,
1668 content: "\n // Do debug accesses\n ".to_string(),
1669 statements: vec![Statement::Comment("// Do debug accesses".to_string())]
1670 }
1671 .into()
1672 ]
1673 );
1674 }
1675
1676 #[test]
1677 fn sequence_missing_name_attribute() {
1678 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
1679<sequence>
1680 <block>Write32(0x40000000, 0x1);</block>
1681</sequence>"#;
1682 let document = Document::parse(xml_str).unwrap();
1683 let node = document.root_element();
1684 let result: Result<Sequence, _> = node.try_into();
1685 let err = result.unwrap_err();
1686 let crate::Error::Family(inner) = err else {
1687 panic!("wrong error type")
1688 };
1689 assert_eq!(
1690 inner,
1691 FamilyParseError::MissingAttribute("name".to_string())
1692 );
1693 }
1694
1695 #[test]
1696 fn sequence_element_unknown_tag() {
1697 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
1698<unknown/>"#;
1699 let document = Document::parse(xml_str).unwrap();
1700 let node = document.root_element();
1701 let result: Result<SequenceElement, _> = node.try_into();
1702 let err = result.unwrap_err();
1703 let crate::Error::Family(inner) = err else {
1704 panic!("wrong error type")
1705 };
1706 assert_eq!(
1707 inner,
1708 FamilyParseError::UnknownElementType("unknown".to_string())
1709 );
1710 }
1711
1712 #[test]
1713 fn debugvar_missing_var_prefix() {
1714 use crate::family::Debugvars;
1715 let result = Debugvars::parse_single_debugvar(" myVar = 0x1;");
1716 assert!(matches!(
1717 result,
1718 Err(FamilyParseError::MalformedDebugvar(_))
1719 ));
1720 }
1721
1722 #[test]
1723 fn debugvar_empty_segment() {
1724 use crate::family::Debugvars;
1725 let result = Debugvars::parse_single_debugvar(" ");
1726 assert!(matches!(
1727 result,
1728 Err(FamilyParseError::MalformedDebugvar(_))
1729 ));
1730 }
1731
1732 #[test]
1733 fn parse_control_element_while() {
1734 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
1735<control while="whileCondition" timeout="5000">
1736 <block>
1737 // Execute while "whileCondition" different from '0' with a timeout of 5ms
1738 whileCondition = 0;
1739 </block>
1740</control>"#;
1741
1742 let document = Document::parse(xml_str).unwrap();
1743 let sequence_node = document.root_element();
1744 let raw_node: RawNode = RawNode(sequence_node);
1745
1746 let block: SequenceControl = raw_node.0.try_into().unwrap();
1747
1748 println!("{:#?}", block);
1749 assert_eq!(block.info, None);
1750 assert_eq!(block.conditional_if, None);
1751 assert_eq!(block.conditional_while, Some("whileCondition".to_string()));
1752 assert_eq!(block.timeout, Some(5000));
1753 assert_eq!(block.elements, vec![
1754 SequenceBlock{
1755 atomic: None,
1756 info: None,
1757 content: r#"
1758 // Execute while "whileCondition" different from '0' with a timeout of 5ms
1759 whileCondition = 0;
1760 "#.to_string(),
1761 statements: vec![
1762 Statement::Comment("// Execute while \"whileCondition\" different from '0' with a timeout of 5ms".to_string()),
1763 Statement::Assignment(Assignment {
1764 variable: "whileCondition".to_string(),
1765 expression: Expression::Normal("0".to_string())
1766 })
1767 ]
1768 }.into()
1769 ]);
1770 }
1771
1772 #[test]
1773 fn parse_family_with_description() {
1774 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
1776<family Dfamily="STM32F1" Dvendor="STMicroelectronics:13">
1777 <description>STM32F1 Arm Cortex-M3 microcontroller series</description>
1778 <debugvars></debugvars>
1779 <sequences/>
1780</family>"#;
1781 let document = Document::parse(xml_str).unwrap();
1782 let family: crate::family::Family = serde_roxmltree::from_doc(&document).unwrap();
1783 assert_eq!(
1784 family.description,
1785 vec!["STM32F1 Arm Cortex-M3 microcontroller series".to_string()]
1786 );
1787 assert_eq!(family.processor.len(), 0);
1788 }
1789
1790 #[test]
1791 fn parse_family_processor() {
1792 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
1793<family Dfamily="LPC" Dvendor="NXP:11">
1794 <processor Pname="Cortex-M3" Dcore="Cortex-M3" Dfpu="NO_FPU" Dmpu="NO_MPU" Dclock="120000000"/>
1795 <debugvars></debugvars>
1796 <sequences/>
1797</family>"#;
1798 let document = Document::parse(xml_str).unwrap();
1799 let family: crate::family::Family = serde_roxmltree::from_doc(&document).unwrap();
1800 assert_eq!(family.processor.len(), 1);
1801 let p = &family.processor[0];
1802 assert_eq!(p.pname, Some("Cortex-M3".to_string()));
1803 assert_eq!(p.dcore, Some("Cortex-M3".to_string()));
1804 assert_eq!(p.dfpu, Some("NO_FPU".to_string()));
1805 assert_eq!(p.dclock, Some(120_000_000));
1806 }
1807
1808 #[test]
1809 fn parse_family_algorithm() {
1810 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
1811<family Dfamily="STM32F1" Dvendor="STMicroelectronics:13">
1812 <algorithm name="Flash/STM32F1xx_128.FLM" start="0x08000000" size="0x00020000"
1813 RAMstart="0x20000000" RAMsize="0x00001000" default="true"/>
1814 <debugvars></debugvars>
1815 <sequences/>
1816</family>"#;
1817 let document = Document::parse(xml_str).unwrap();
1818 let family: crate::family::Family = serde_roxmltree::from_doc(&document).unwrap();
1819 assert_eq!(family.algorithm.len(), 1);
1820 let a = &family.algorithm[0];
1821 assert_eq!(a.name, "Flash/STM32F1xx_128.FLM");
1822 assert_eq!(a.start, Some("0x08000000".to_string()));
1823 assert_eq!(a.size, Some("0x00020000".to_string()));
1824 assert_eq!(a.ram_start, Some("0x20000000".to_string()));
1825 assert_eq!(a.ram_size, Some("0x00001000".to_string()));
1826 assert_eq!(a.default, Some(true));
1827 assert_eq!(a.device_index, None);
1828 assert_eq!(a.parameter, None);
1829 assert_eq!(a.endian, "Little-endian");
1830 }
1831
1832 #[test]
1833 fn parse_family_memory() {
1834 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
1835<family Dfamily="STM32F1" Dvendor="STMicroelectronics:13">
1836 <memory name="IROM1" access="rx" start="0x08000000" size="0x00020000" startup="true" default="true"/>
1837 <memory name="IRAM1" access="rw" start="0x20000000" size="0x00005000" uninit="true" default="true"/>
1838 <debugvars></debugvars>
1839 <sequences/>
1840</family>"#;
1841 let document = Document::parse(xml_str).unwrap();
1842 let family: crate::family::Family = serde_roxmltree::from_doc(&document).unwrap();
1843 assert_eq!(family.memory.len(), 2);
1844 let rom = &family.memory[0];
1845 assert_eq!(rom.name, Some("IROM1".to_string()));
1846 assert_eq!(rom.access, Some("rx".to_string()));
1847 assert_eq!(rom.start, "0x08000000");
1848 assert_eq!(rom.startup, Some(true));
1849 assert_eq!(rom.default, Some(true));
1850 let ram = &family.memory[1];
1851 assert_eq!(ram.uninit, Some(true));
1852 }
1853
1854 #[test]
1855 fn parse_family_book() {
1856 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
1857<family Dfamily="STM32F1" Dvendor="STMicroelectronics:13">
1858 <book name="Docs/DM00031936.pdf" title="STM32F1 Reference Manual"/>
1859 <debugvars></debugvars>
1860 <sequences/>
1861</family>"#;
1862 let document = Document::parse(xml_str).unwrap();
1863 let family: crate::family::Family = serde_roxmltree::from_doc(&document).unwrap();
1864 assert_eq!(family.book.len(), 1);
1865 assert_eq!(family.book[0].name, "Docs/DM00031936.pdf");
1866 assert_eq!(family.book[0].title, "STM32F1 Reference Manual");
1867 assert_eq!(family.book[0].public, None);
1868 }
1869
1870 #[test]
1871 fn parse_family_feature() {
1872 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
1873<family Dfamily="STM32F1" Dvendor="STMicroelectronics:13">
1874 <feature type="UART" n="3" name="Universal Asynchronous Receiver/Transmitter"/>
1875 <feature type="ADC" n="1" m="12"/>
1876 <debugvars></debugvars>
1877 <sequences/>
1878</family>"#;
1879 let document = Document::parse(xml_str).unwrap();
1880 let family: crate::family::Family = serde_roxmltree::from_doc(&document).unwrap();
1881 assert_eq!(family.feature.len(), 2);
1882 assert_eq!(family.feature[0].feature_type, "UART");
1883 assert_eq!(family.feature[0].n, Some("3".to_string()));
1884 assert_eq!(
1885 family.feature[0].name,
1886 Some("Universal Asynchronous Receiver/Transmitter".to_string())
1887 );
1888 assert_eq!(family.feature[1].m, Some("12".to_string()));
1889 }
1890
1891 #[test]
1892 fn parse_family_feature_count() {
1893 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
1895<family Dfamily="STM32F1" Dvendor="STMicroelectronics:13">
1896 <feature type="UART" n="3" count="2"/>
1897 <feature type="ADC" n="1" m="12"/>
1898 <debugvars></debugvars>
1899 <sequences/>
1900</family>"#;
1901 let document = Document::parse(xml_str).unwrap();
1902 let family: crate::family::Family = serde_roxmltree::from_doc(&document).unwrap();
1903 assert_eq!(family.feature[0].count, Some(2));
1904 assert_eq!(family.feature[1].count, None);
1905 }
1906
1907 #[test]
1908 fn parse_family_debug_and_debugconfig() {
1909 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
1910<family Dfamily="STM32F1" Dvendor="STMicroelectronics:13">
1911 <debug svd="SVD/STM32F103xx.svd" __dp="0" __ap="0"/>
1912 <debugconfig default="swd" clock="5000000" swj="true"/>
1913 <debugvars></debugvars>
1914 <sequences/>
1915</family>"#;
1916 let document = Document::parse(xml_str).unwrap();
1917 let family: crate::family::Family = serde_roxmltree::from_doc(&document).unwrap();
1918 assert_eq!(family.debug.len(), 1);
1919 assert_eq!(family.debug[0].svd, Some("SVD/STM32F103xx.svd".to_string()));
1920 assert_eq!(family.debug[0].dp, Some(0));
1921 assert_eq!(family.debug[0].ap, Some(0));
1922 let dc = family.debugconfig.as_ref().unwrap();
1923 assert_eq!(dc.default, Some("swd".to_string()));
1924 assert_eq!(dc.clock, Some(5_000_000));
1925 assert_eq!(dc.swj, Some(true));
1926 }
1927
1928 #[test]
1929 fn parse_family_debugport() {
1930 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
1931<family Dfamily="STM32F1" Dvendor="STMicroelectronics:13">
1932 <debugport __dp="0">
1933 <swd/>
1934 <jtag tapindex="0"/>
1935 </debugport>
1936 <debugvars></debugvars>
1937 <sequences/>
1938</family>"#;
1939 let document = Document::parse(xml_str).unwrap();
1940 let family: crate::family::Family = serde_roxmltree::from_doc(&document).unwrap();
1941 assert_eq!(family.debugport.len(), 1);
1942 let dp = &family.debugport[0];
1943 assert_eq!(dp.dp, Some(0));
1944 assert!(dp.swd.is_some());
1945 assert!(dp.jtag.is_some());
1946 assert_eq!(dp.jtag.as_ref().unwrap().tapindex, Some(0));
1947 }
1948
1949 #[test]
1950 fn parse_family_access_ports() {
1951 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
1952<family Dfamily="STM32F1" Dvendor="STMicroelectronics:13">
1953 <accessportV1 __apid="0" __dp="0" index="0"/>
1954 <accessportV2 __apid="1" __dp="0" address="0xE0041000"/>
1955 <debugvars></debugvars>
1956 <sequences/>
1957</family>"#;
1958 let document = Document::parse(xml_str).unwrap();
1959 let family: crate::family::Family = serde_roxmltree::from_doc(&document).unwrap();
1960 assert_eq!(family.access_port_v1.len(), 1);
1961 assert_eq!(family.access_port_v1[0].apid, 0);
1962 assert_eq!(family.access_port_v1[0].dp, Some(0));
1963 assert_eq!(family.access_port_v1[0].index, 0);
1964 assert_eq!(family.access_port_v2.len(), 1);
1965 assert_eq!(family.access_port_v2[0].apid, 1);
1966 assert_eq!(family.access_port_v2[0].address, "0xE0041000");
1967 }
1968
1969 #[test]
1970 fn parse_family_compile() {
1971 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
1972<family Dfamily="STM32F1" Dvendor="STMicroelectronics:13">
1973 <compile header="Include/stm32f1xx.h" define="STM32F1"/>
1974 <debugvars></debugvars>
1975 <sequences/>
1976</family>"#;
1977 let document = Document::parse(xml_str).unwrap();
1978 let family: crate::family::Family = serde_roxmltree::from_doc(&document).unwrap();
1979 assert_eq!(family.compile.len(), 1);
1980 assert_eq!(
1981 family.compile[0].header,
1982 Some("Include/stm32f1xx.h".to_string())
1983 );
1984 assert_eq!(family.compile[0].define, Some("STM32F1".to_string()));
1985 }
1986
1987 #[test]
1988 fn parse_family_flashinfo() {
1989 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
1990<family Dfamily="STM32F1" Dvendor="STMicroelectronics:13">
1991 <flashinfo name="Flash" start="0x08000000" pagesize="0x400" blankval="0xFF">
1992 <block count="128" size="0x400"/>
1993 </flashinfo>
1994 <debugvars></debugvars>
1995 <sequences/>
1996</family>"#;
1997 let document = Document::parse(xml_str).unwrap();
1998 let family: crate::family::Family = serde_roxmltree::from_doc(&document).unwrap();
1999 assert_eq!(family.flashinfo_raw.len(), 1);
2000 let flashinfo = parse_flashinfo(&family.flashinfo_raw).unwrap();
2001 assert_eq!(flashinfo.len(), 1);
2002 let fi = &flashinfo[0];
2003 assert_eq!(fi.name, "Flash");
2004 assert_eq!(fi.start, "0x08000000");
2005 assert_eq!(fi.pagesize, "0x400");
2006 assert_eq!(fi.blankval, Some("0xFF".to_string()));
2007 assert_eq!(
2008 fi.elements,
2009 vec![FlashInfoElement::Block(FlashBlock {
2010 count: 128,
2011 size: "0x400".to_string(),
2012 arg: None,
2013 })]
2014 );
2015 }
2016
2017 #[test]
2018 fn parse_family_flashinfo_interleaved_order() {
2019 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
2020<family Dfamily="STM32F1" Dvendor="STMicroelectronics:13">
2021 <flashinfo name="Flash" start="0x08000000" pagesize="0x400" blankval="0xFF">
2022 <gap size="0x10"/>
2023 <block count="128" size="0x400"/>
2024 <gap size="0x20"/>
2025 </flashinfo>
2026 <debugvars></debugvars>
2027 <sequences/>
2028</family>"#;
2029 let document = Document::parse(xml_str).unwrap();
2030 let family: crate::family::Family = serde_roxmltree::from_doc(&document).unwrap();
2031 let flashinfo = parse_flashinfo(&family.flashinfo_raw).unwrap();
2032 assert_eq!(flashinfo.len(), 1);
2033 assert_eq!(
2034 flashinfo[0].elements,
2035 vec![
2036 FlashInfoElement::Gap(FlashGap {
2037 size: "0x10".to_string(),
2038 }),
2039 FlashInfoElement::Block(FlashBlock {
2040 count: 128,
2041 size: "0x400".to_string(),
2042 arg: None,
2043 }),
2044 FlashInfoElement::Gap(FlashGap {
2045 size: "0x20".to_string(),
2046 }),
2047 ]
2048 );
2049 }
2050
2051 #[test]
2052 fn parse_family_trace() {
2053 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
2054<family Dfamily="STM32F1" Dvendor="STMicroelectronics:13">
2055 <trace Pname="Core0">
2056 <serialwire/>
2057 <traceport width="4"/>
2058 <tracebuffer start="0xE0041000" size="0x1000"/>
2059 </trace>
2060 <debugvars></debugvars>
2061 <sequences/>
2062</family>"#;
2063 let document = Document::parse(xml_str).unwrap();
2064 let family: crate::family::Family = serde_roxmltree::from_doc(&document).unwrap();
2065 assert_eq!(family.trace.len(), 1);
2066 let trace = &family.trace[0];
2067 assert_eq!(trace.pname, Some("Core0".to_string()));
2068 assert_eq!(trace.serialwire.len(), 1);
2069 assert_eq!(trace.traceport.len(), 1);
2070 assert_eq!(trace.traceport[0].width, Some(4));
2071 assert_eq!(trace.tracebuffer.len(), 1);
2072 assert_eq!(trace.tracebuffer[0].start, Some("0xE0041000".to_string()));
2073 assert_eq!(trace.tracebuffer[0].size, Some("0x1000".to_string()));
2074 }
2075
2076 #[test]
2077 fn parse_family_environment() {
2078 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
2079<family Dfamily="STM32F1" Dvendor="STMicroelectronics:13">
2080 <environment name="uv" Pname="Core0"/>
2081 <debugvars></debugvars>
2082 <sequences/>
2083</family>"#;
2084 let document = Document::parse(xml_str).unwrap();
2085 let family: crate::family::Family = serde_roxmltree::from_doc(&document).unwrap();
2086 assert_eq!(family.environment.len(), 1);
2087 assert_eq!(family.environment[0].name, "uv");
2088 assert_eq!(family.environment[0].pname, Some("Core0".to_string()));
2089 }
2090
2091 #[test]
2092 fn parse_device_basic() {
2093 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
2094<device Dname="PIC32CM1216PL10028">
2095 <processor Dcore="Cortex-M0+" Dendian="Little-endian" Dmpu="NO_MPU" Dfpu="NO_FPU"
2096 Ddsp="NO_DSP" Dtz="NO_TZ" Dmve="NO_MVE" Dclock="24000000" DcoreVersion="r0p0"/>
2097 <memory name="FLASH" start="0x0C000000" size="0x20000" access="rx" default="1" startup="1"/>
2098 <memory name="HSRAM" start="0x20000000" size="0x4000" default="1" access="rwx"/>
2099</device>"#;
2100 let document = Document::parse(xml_str).unwrap();
2101 let device: crate::family::Device = serde_roxmltree::from_doc(&document).unwrap();
2102 assert_eq!(device.device_name, "PIC32CM1216PL10028");
2103 assert_eq!(device.processor.len(), 1);
2104 assert_eq!(device.processor[0].dcore, Some("Cortex-M0+".to_string()));
2105 assert_eq!(device.processor[0].dclock, Some(24000000));
2106 assert_eq!(device.memory.len(), 2);
2107 assert_eq!(device.memory[0].name, Some("FLASH".to_string()));
2108 assert_eq!(device.memory[0].start, "0x0C000000");
2109 assert_eq!(device.memory[1].name, Some("HSRAM".to_string()));
2110 assert_eq!(device.variants.len(), 0);
2111 }
2112
2113 #[test]
2114 fn parse_device_with_variant() {
2115 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
2116<device Dname="LPC1768">
2117 <processor Dcore="Cortex-M3" Dclock="100000000"/>
2118 <variant Dvariant="LPC1768FBD100">
2119 <memory name="FLASH" start="0x00000000" size="0x80000" access="rx"/>
2120 </variant>
2121 <variant Dvariant="LPC1768FET100">
2122 <processor Dcore="Cortex-M3" Dclock="120000000"/>
2123 </variant>
2124</device>"#;
2125 let document = Document::parse(xml_str).unwrap();
2126 let device: crate::family::Device = serde_roxmltree::from_doc(&document).unwrap();
2127 assert_eq!(device.device_name, "LPC1768");
2128 assert_eq!(device.variants.len(), 2);
2129 assert_eq!(device.variants[0].variant_name, "LPC1768FBD100");
2130 assert_eq!(device.variants[0].memory.len(), 1);
2131 assert_eq!(device.variants[1].variant_name, "LPC1768FET100");
2132 assert_eq!(device.variants[1].processor[0].dclock, Some(120000000));
2133 }
2134
2135 #[test]
2136 fn parse_subfamily_with_devices() {
2137 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
2138<subFamily DsubFamily="LPC176x">
2139 <processor Dcore="Cortex-M3"/>
2140 <device Dname="LPC1768">
2141 <processor Dclock="100000000"/>
2142 <memory name="FLASH" start="0x00000000" size="0x80000" access="rx"/>
2143 </device>
2144 <device Dname="LPC1766">
2145 <processor Dclock="100000000"/>
2146 <memory name="FLASH" start="0x00000000" size="0x40000" access="rx"/>
2147 </device>
2148</subFamily>"#;
2149 let document = Document::parse(xml_str).unwrap();
2150 let sf: crate::family::SubFamily = serde_roxmltree::from_doc(&document).unwrap();
2151 assert_eq!(sf.sub_family_name, "LPC176x");
2152 assert_eq!(sf.processor.len(), 1);
2153 assert_eq!(sf.processor[0].dcore, Some("Cortex-M3".to_string()));
2154 assert_eq!(sf.devices.len(), 2);
2155 assert_eq!(sf.devices[0].device_name, "LPC1768");
2156 assert_eq!(sf.devices[0].memory[0].size, "0x80000");
2157 assert_eq!(sf.devices[1].device_name, "LPC1766");
2158 }
2159
2160 #[test]
2161 fn parse_family_with_direct_devices() {
2162 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
2163<family Dfamily="PIC32CM-PL" Dvendor="Microchip:3">
2164 <debugvars configfile="debug.dbgconf" version="1.0.0">__var myVar = 0x1;</debugvars>
2165 <sequences/>
2166 <device Dname="PIC32CM1216PL10028">
2167 <processor Dcore="Cortex-M0+" Dclock="24000000"/>
2168 <debugconfig default="swd" clock="2000000"/>
2169 <compile header="pic32cm1216pl/include/pic32c.h" define="__PIC32CM1216PL10028__"/>
2170 <memory name="FLASH" start="0x0C000000" size="0x20000" access="rx"/>
2171 <algorithm name="keil/Flash/PIC32CM-PL_FLASH_128.FLM" start="0x0C000000" size="0x20000"
2172 RAMstart="0x20000000" RAMsize="0x2000" default="1" style="Keil"/>
2173 </device>
2174 <device Dname="PIC32CM2532PL10028">
2175 <processor Dcore="Cortex-M0+" Dclock="24000000"/>
2176 <memory name="FLASH" start="0x0C000000" size="0x40000" access="rx"/>
2177 </device>
2178</family>"#;
2179 let document = Document::parse(xml_str).unwrap();
2180 let family: crate::family::Family = serde_roxmltree::from_doc(&document).unwrap();
2181 assert_eq!(family.device_family, "PIC32CM-PL");
2182 assert_eq!(family.devices.len(), 2);
2183 assert_eq!(family.sub_families.len(), 0);
2184
2185 let d0 = &family.devices[0];
2186 assert_eq!(d0.device_name, "PIC32CM1216PL10028");
2187 assert_eq!(d0.processor[0].dcore, Some("Cortex-M0+".to_string()));
2188 assert_eq!(
2189 d0.debugconfig.as_ref().unwrap().default,
2190 Some("swd".to_string())
2191 );
2192 assert_eq!(
2193 d0.compile[0].header,
2194 Some("pic32cm1216pl/include/pic32c.h".to_string())
2195 );
2196 assert_eq!(d0.memory[0].name, Some("FLASH".to_string()));
2197 assert_eq!(d0.algorithm[0].name, "keil/Flash/PIC32CM-PL_FLASH_128.FLM");
2198 assert_eq!(d0.algorithm[0].default, Some(true));
2199
2200 let d1 = &family.devices[1];
2201 assert_eq!(d1.device_name, "PIC32CM2532PL10028");
2202 assert_eq!(d1.memory[0].size, "0x40000");
2203 }
2204
2205 #[test]
2206 fn parse_deprecated_element() {
2207 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
2210<family Dfamily="STM32F1" Dvendor="STMicroelectronics:13">
2211 <deprecated>2020-01-01</deprecated>
2212 <debugvars></debugvars>
2213 <sequences/>
2214 <subFamily DsubFamily="STM32F103">
2215 <deprecated>2020-02-02</deprecated>
2216 </subFamily>
2217 <device Dname="STM32F103C8">
2218 <deprecated>2020-03-03</deprecated>
2219 <variant Dvariant="STM32F103C8Tx">
2220 <deprecated>2020-04-04</deprecated>
2221 </variant>
2222 </device>
2223</family>"#;
2224 let document = Document::parse(xml_str).unwrap();
2225 let family: crate::family::Family = serde_roxmltree::from_doc(&document).unwrap();
2226 assert_eq!(family.deprecated, Some("2020-01-01".to_string()));
2227 assert_eq!(
2228 family.sub_families[0].deprecated,
2229 Some("2020-02-02".to_string())
2230 );
2231 assert_eq!(family.devices[0].deprecated, Some("2020-03-03".to_string()));
2232 assert_eq!(
2233 family.devices[0].variants[0].deprecated,
2234 Some("2020-04-04".to_string())
2235 );
2236 }
2237
2238 #[test]
2239 fn parse_variant_debugvars_and_sequences() {
2240 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
2243<device Dname="LPC1768">
2244 <variant Dvariant="LPC1768FBD100">
2245 <debugvars configfile="debug.dbgconf" version="1.0.0">__var myVar = 0x1;</debugvars>
2246 <sequences/>
2247 </variant>
2248</device>"#;
2249 let document = Document::parse(xml_str).unwrap();
2250 let mut device: crate::family::Device = serde_roxmltree::from_doc(&document).unwrap();
2251 assert_eq!(device.variants.len(), 1);
2252 device.variants[0].debugvars =
2253 crate::family::merge_debugvars(&device.variants[0].debugvars_raw).unwrap();
2254 assert_eq!(
2255 device.variants[0].debugvars.configfile,
2256 Some("debug.dbgconf".to_string())
2257 );
2258 assert_eq!(
2259 device.variants[0].debugvars.version,
2260 Some("1.0.0".to_string())
2261 );
2262 }
2263
2264 #[test]
2265 fn parse_family_debugvars_multiple_siblings() {
2266 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
2269<family Dfamily="STM32F1" Dvendor="STMicroelectronics:13">
2270 <debugvars configfile="debug.dbgconf" version="1.0.0">__var myVar = 0x1;</debugvars>
2271 <debugvars>__var otherVar = 0x2;</debugvars>
2272 <sequences/>
2273</family>"#;
2274 let document = Document::parse(xml_str).unwrap();
2275 let mut family: crate::family::Family = serde_roxmltree::from_doc(&document).unwrap();
2276 assert_eq!(family.debugvars_raw.len(), 2);
2277
2278 family.debugvars = crate::family::merge_debugvars(&family.debugvars_raw).unwrap();
2279 assert_eq!(
2280 family.debugvars.configfile,
2281 Some("debug.dbgconf".to_string())
2282 );
2283 assert_eq!(family.debugvars.version, Some("1.0.0".to_string()));
2284
2285 family.debugvars.parse_debugvars();
2286 let parsed = family.debugvars.parsed_debugvars.unwrap();
2287 assert_eq!(parsed.get("myVar"), Some(&1));
2288 assert_eq!(parsed.get("otherVar"), Some(&2));
2289 }
2290
2291 #[test]
2292 fn parse_family_sequences_multiple_siblings() {
2293 let xml_str = r#"<?xml version="1.0" encoding="UTF-8"?>
2297<family Dfamily="STM32F1" Dvendor="STMicroelectronics:13">
2298 <debugvars></debugvars>
2299 <sequences traceSetup="full">
2300 <sequence name="SeqA">
2301 <block>Sequence("A");</block>
2302 </sequence>
2303 </sequences>
2304 <sequences>
2305 <sequence name="SeqB">
2306 <block>Sequence("B");</block>
2307 </sequence>
2308 </sequences>
2309</family>"#;
2310 let document = Document::parse(xml_str).unwrap();
2311 let mut family: crate::family::Family = serde_roxmltree::from_doc(&document).unwrap();
2312 assert_eq!(family.sequences_raw.len(), 2);
2313
2314 family.sequences = crate::family::merge_sequences(&family.sequences_raw).unwrap();
2315 assert_eq!(family.sequences.trace_setup, Some(TraceSetup::Full));
2316 assert_eq!(family.sequences.raw_nodes.len(), 2);
2317
2318 family.sequences.parse_sequences().unwrap();
2319 assert_eq!(family.sequences.sequences.len(), 2);
2320 assert_eq!(family.sequences.sequences[0].name, "SeqA");
2321 assert_eq!(family.sequences.sequences[1].name, "SeqB");
2322 }
2323}