-
Notifications
You must be signed in to change notification settings - Fork 13
Implement union peripherals with clustering (TCA single mode / split mode on attiny's) #79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
f4b2dc0
f9b07a5
041c66e
d2428ed
035344c
2b09f9d
c74b75e
b35963a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -84,3 +84,150 @@ pub fn parse( | |||||
| fields, | ||||||
| }) | ||||||
| } | ||||||
|
|
||||||
| pub fn parse_list( | ||||||
| register_group_header_el: &xmltree::Element, | ||||||
| offset: usize, | ||||||
| value_groups: &atdf::values::ValueGroups, | ||||||
| ) -> crate::Result<BTreeMap<String, chip::Register>> { | ||||||
| let mut registers = vec![]; | ||||||
|
|
||||||
| for register in | ||||||
| register_group_header_el.iter_children_with_name("register", Some("register-group")) | ||||||
| { | ||||||
| registers.push(atdf::register::parse(register, offset, value_groups)?); | ||||||
| } | ||||||
| Ok(registers | ||||||
| .into_iter() | ||||||
| .map(|r| { | ||||||
| ( | ||||||
| match r.mode { | ||||||
| Some(ref mode) => format!("{mode}_{}", r.name), | ||||||
| _ => r.name.clone(), | ||||||
| }, | ||||||
| r, | ||||||
| ) | ||||||
| }) | ||||||
| .collect()) | ||||||
| } | ||||||
|
|
||||||
| pub fn parse_register_group_headers( | ||||||
| module_el: &xmltree::Element, | ||||||
| offset: usize, | ||||||
| value_groups: &atdf::values::ValueGroups, | ||||||
| ) -> crate::Result<BTreeMap<String, chip::RegisterGroupHeader>> { | ||||||
| let mut register_group_headers = BTreeMap::new(); | ||||||
| for register_group_header_el in module_el | ||||||
| .children | ||||||
| .iter() | ||||||
| .filter_map(|node| node.as_element().filter(|e| e.name == "register-group")) | ||||||
| { | ||||||
| let name = register_group_header_el.attr("name")?.clone(); | ||||||
| let class = register_group_header_el | ||||||
| .attributes | ||||||
| .get("class") | ||||||
| .and_then(|d| if !d.is_empty() { Some(d) } else { None }) | ||||||
|
||||||
| .and_then(|d| if !d.is_empty() { Some(d) } else { None }) | |
| .filter(|d| !d.is_empty()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed class from the register group struct
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| .and_then(|d| if !d.is_empty() { Some(d) } else { None }) | |
| .filter(|d| !d.is_empty()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
applied in register_group.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here about .ok() on the parse_int() result.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed the size code
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| .and_then(|d| if !d.is_empty() { Some(d) } else { None }) | |
| .filter(|d| !d.is_empty()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed description from the reference in register_group.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| .and_then(|d| if !d.is_empty() { Some(d) } else { None }) | |
| .filter(|d| !d.is_empty()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
applied in register_group.rs reference struct
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is dangerous, you silently place None into the size when parsing the number fails. You should propagate the error outwards, e.g. using
| util::parse_int(d).ok() | |
| Some(util::parse_int(d)?) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the size code was removed
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, don't .ok() the parse_int() result. Propagating the error gets a little more difficult, though. I think I would do it like this:
let offset = register_group_item_el
.attributes
.get("offset")
.filter(|d| !d.is_empty())
.map(|d| d.parse::<usize>())
.transpose()?;There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
applied in register_group.rs reference
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And same error silencing problem here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the count code was removed
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,15 +18,57 @@ pub struct Chip { | |
| #[derive(Debug, Clone)] | ||
| pub struct Peripheral { | ||
| pub name: String, | ||
| pub name_in_module: String, | ||
| pub description: Option<String>, | ||
|
|
||
| pub registers: BTreeMap<String, Register>, | ||
| pub register_group_headers: BTreeMap<String, RegisterGroupHeader>, | ||
| } | ||
|
|
||
| impl Peripheral { | ||
| pub fn base_address(&self) -> Option<usize> { | ||
| if self.is_union() { | ||
| return self | ||
| .get_union_register_group_headers() | ||
| .iter() | ||
| .flat_map(|(h, _)| h.registers.values()) | ||
| .map(|r| r.address) | ||
| .min(); | ||
| } | ||
| self.registers.values().map(|r| r.address).min() | ||
|
||
| } | ||
|
|
||
| pub fn module_register_group_header(&self) -> Option<&RegisterGroupHeader> { | ||
| self.register_group_headers.get(&self.name_in_module) | ||
| } | ||
|
|
||
| pub fn is_union(&self) -> bool { | ||
| let module_register_group_header = self.module_register_group_header(); | ||
| match module_register_group_header { | ||
| Some(header) => header.is_union(), | ||
| None => false, | ||
| } | ||
| } | ||
|
|
||
| pub fn get_union_register_group_headers( | ||
| &self, | ||
| ) -> Vec<(&RegisterGroupHeader, &RegisterGroupItem)> { | ||
| match self.module_register_group_header() { | ||
| Some(module_header) if module_header.is_union() => module_header | ||
| .register_group_items | ||
| .values() | ||
| .filter_map(|group_item| { | ||
| group_item.name_in_module.as_ref().and_then(|header_name| { | ||
| self.register_group_headers | ||
| .iter() | ||
| .find(|(_, header)| &header.name == header_name) | ||
| .map(|(_, header)| (header, group_item)) | ||
| }) | ||
| }) | ||
| .collect(), | ||
| _ => vec![], | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #[derive(Debug, Clone)] | ||
|
|
@@ -52,6 +94,33 @@ pub enum ValueRestriction { | |
| Enumerated(BTreeMap<String, EnumeratedValue>), | ||
| } | ||
|
|
||
| #[derive(Debug, Clone)] | ||
| pub struct RegisterGroupHeader { | ||
| pub name: String, | ||
| pub class: Option<String>, | ||
|
||
| pub description: Option<String>, | ||
| pub size: Option<usize>, | ||
|
|
||
| pub register_group_items: BTreeMap<String, RegisterGroupItem>, | ||
| pub registers: BTreeMap<String, Register>, | ||
| } | ||
|
|
||
| impl RegisterGroupHeader { | ||
| pub fn is_union(&self) -> bool { | ||
| self.class.as_deref() == Some("union") | ||
| } | ||
| } | ||
|
|
||
| #[derive(Debug, Clone)] | ||
| pub struct RegisterGroupItem { | ||
| pub name: String, | ||
| pub name_in_module: Option<String>, | ||
| pub description: Option<String>, | ||
| pub size: Option<usize>, | ||
| pub offset: Option<usize>, | ||
| pub count: Option<usize>, | ||
|
||
| } | ||
|
|
||
| #[derive(Debug, Clone)] | ||
| pub struct Register { | ||
| pub name: String, | ||
|
|
||

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(And you can actually drop the
.collect()because you are going to just turn theVecinto an iterator again two lines below)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I merged the 2 statements into 1