Skip to content

Commit 1b908c1

Browse files
authored
Merge pull request #181 from rust-embedded/expand
mmaps arrays
2 parents 3a9da02 + ed29bb1 commit 1b908c1

File tree

4 files changed

+54
-47
lines changed

4 files changed

+54
-47
lines changed

.github/workflows/ci.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
- name: Checkout code
2727
uses: actions/checkout@v4
2828
- name: Install Python
29-
uses: actions/setup-python@v2
29+
uses: actions/setup-python@v4
3030
with:
3131
python-version: 3.9
3232
- name: Install svdtools
@@ -55,7 +55,7 @@ jobs:
5555
- name: Checkout code
5656
uses: actions/checkout@v4
5757
- name: Install Python
58-
uses: actions/setup-python@v2
58+
uses: actions/setup-python@v4
5959
with:
6060
python-version: 3.9
6161
- name: Install svdtools

CHANGELOG-rust.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This changelog tracks the Rust `svdtools` project. See
77

88
* Move field with derived enums before other
99
* `-1` for default enum value
10+
* mmaps: peripheral arrays, bump `svd` crates
1011

1112
## [v0.3.4] 2023-10-14
1213

Cargo.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ rust-version = "1.70"
2828
clap = { version = "4.1", features = ["derive", "cargo", "color"] }
2929
serde = { version = "1.0", features = ["derive"] }
3030
quick-xml = { version = "0.30", features = ["serialize"] }
31-
svd-rs = { version = "0.14.2", features = ["serde", "derive-from"] }
32-
svd-parser = { version = "0.14.2", features = ["expand"] }
33-
svd-encoder = "0.14.3"
31+
svd-rs = { version = "0.14.4", features = ["serde", "derive-from"] }
32+
svd-parser = { version = "0.14.3", features = ["expand"] }
33+
svd-encoder = "0.14.4"
3434
yaml-rust = "0.4"
3535
# serde_yaml 0.9.x looks broken
3636
serde_yaml = "0.8.26"

src/mmap/mmap_cli.rs

+48-42
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ use crate::common::svd_reader;
22
use crate::common::{str_utils, svd_utils};
33
use anyhow::{Context, Result};
44
use std::{fs::File, io::Read, path::Path};
5-
use svd_parser::svd::{Cluster, Field, Peripheral, Register, RegisterCluster, RegisterInfo};
5+
use svd::PeripheralInfo;
6+
use svd_parser::svd::{self, Cluster, Field, Peripheral, Register, RegisterCluster, RegisterInfo};
67

78
/// Output sorted text of every peripheral, register, field, and interrupt
89
/// in the device, such that automated diffing is possible.
@@ -29,18 +30,30 @@ fn to_text(peripherals: &[Peripheral]) -> String {
2930
let mut mmap: Vec<String> = vec![];
3031

3132
for p in peripherals {
32-
get_peripheral(p, &mut mmap);
33-
get_interrupts(p, &mut mmap);
34-
let registers = get_periph_registers(p, peripherals);
35-
get_registers(p.base_address, registers.as_ref(), "", &mut mmap);
33+
match p {
34+
Peripheral::Single(p) => {
35+
get_peripheral(p, &mut mmap);
36+
get_interrupts(p, &mut mmap);
37+
let registers = get_periph_registers(p, peripherals);
38+
get_registers(p.base_address, registers.as_ref(), "", &mut mmap);
39+
}
40+
Peripheral::Array(p, d) => {
41+
for pi in svd::peripheral::expand(p, d) {
42+
get_peripheral(&pi, &mut mmap);
43+
get_interrupts(&pi, &mut mmap);
44+
let registers = get_periph_registers(&pi, peripherals);
45+
get_registers(pi.base_address, registers.as_ref(), "", &mut mmap);
46+
}
47+
}
48+
}
3649
}
3750

3851
mmap.sort();
3952
mmap.join("\n")
4053
}
4154

4255
fn get_periph_registers<'a>(
43-
peripheral: &'a Peripheral,
56+
peripheral: &'a PeripheralInfo,
4457
peripheral_list: &'a [Peripheral],
4558
) -> &'a Option<Vec<RegisterCluster>> {
4659
match &peripheral.derived_from {
@@ -58,7 +71,7 @@ fn get_periph_registers<'a>(
5871
}
5972
}
6073

61-
fn get_peripheral(peripheral: &Peripheral, mmap: &mut Vec<String>) {
74+
fn get_peripheral(peripheral: &PeripheralInfo, mmap: &mut Vec<String>) {
6275
let text = format!(
6376
"{} A PERIPHERAL {}",
6477
str_utils::format_address(peripheral.base_address),
@@ -67,7 +80,7 @@ fn get_peripheral(peripheral: &Peripheral, mmap: &mut Vec<String>) {
6780
mmap.push(text);
6881
}
6982

70-
fn get_interrupts(peripheral: &Peripheral, mmap: &mut Vec<String>) {
83+
fn get_interrupts(peripheral: &PeripheralInfo, mmap: &mut Vec<String>) {
7184
for i in &peripheral.interrupt {
7285
let description = str_utils::get_description(&i.description);
7386
let text = format!(
@@ -86,10 +99,6 @@ fn derived_str(dname: &Option<String>) -> String {
8699
}
87100
}
88101

89-
fn replace_idx(name: &str, idx: &str) -> String {
90-
name.replace("[%s]", idx).replace("%s", idx)
91-
}
92-
93102
fn get_registers(
94103
base_address: u64,
95104
registers: Option<&Vec<RegisterCluster>>,
@@ -100,56 +109,54 @@ fn get_registers(
100109
for r in registers {
101110
match &r {
102111
RegisterCluster::Register(r) => {
103-
let description = str_utils::get_description(&r.description);
104112
let access = svd_utils::access_with_brace(r.properties.access);
105-
let first_addr = base_address + r.address_offset as u64;
113+
let derived = derived_str(&r.derived_from);
106114
match r {
107115
Register::Single(r) => {
108-
let addr = str_utils::format_address(first_addr);
116+
let addr =
117+
str_utils::format_address(base_address + r.address_offset as u64);
109118
let rname = r.name.to_string() + suffix;
110-
let derived = derived_str(&r.derived_from);
119+
let description = str_utils::get_description(&r.description);
111120
let text = format!(
112121
"{addr} B REGISTER {rname}{derived}{access}: {description}"
113122
);
114123
mmap.push(text);
115124
get_fields(r, &addr, mmap);
116125
}
117126
Register::Array(r, d) => {
118-
let derived = derived_str(&r.derived_from);
119-
for (i, idx) in d.indexes().enumerate() {
127+
for ri in svd::register::expand(r, d) {
120128
let addr = str_utils::format_address(
121-
first_addr + (i as u64) * (d.dim_increment as u64),
129+
base_address + ri.address_offset as u64,
122130
);
123-
let rname = replace_idx(&r.name, &idx);
124-
let description = replace_idx(&description, &idx);
131+
let rname = &ri.name;
132+
let description = str_utils::get_description(&ri.description);
125133
let text = format!(
126134
"{addr} B REGISTER {rname}{derived}{access}: {description}"
127135
);
128136
mmap.push(text);
129-
get_fields(r, &addr, mmap);
137+
get_fields(&ri, &addr, mmap);
130138
}
131139
}
132140
}
133141
}
134142
RegisterCluster::Cluster(c) => {
135-
let description = str_utils::get_description(&c.description);
136-
let first_addr = base_address + c.address_offset as u64;
143+
let derived = derived_str(&c.derived_from);
137144
match c {
138145
Cluster::Single(c) => {
139-
let addr = str_utils::format_address(first_addr);
146+
let caddr = base_address + c.address_offset as u64;
147+
let addr = str_utils::format_address(caddr);
140148
let cname = &c.name;
141-
let derived = derived_str(&c.derived_from);
149+
let description = str_utils::get_description(&c.description);
142150
let text = format!("{addr} B CLUSTER {cname}{derived}: {description}");
143151
mmap.push(text);
144-
get_registers(first_addr, Some(&c.children), "", mmap);
152+
get_registers(caddr, Some(&c.children), "", mmap);
145153
}
146154
Cluster::Array(c, d) => {
147-
let derived = derived_str(&c.derived_from);
148-
for (i, idx) in d.indexes().enumerate() {
149-
let caddr = first_addr + (i as u64) * (d.dim_increment as u64);
155+
for (ci, idx) in svd::cluster::expand(c, d).zip(d.indexes()) {
156+
let caddr = base_address + ci.address_offset as u64;
150157
let addr = str_utils::format_address(caddr);
151-
let cname = replace_idx(&c.name, &idx);
152-
let description = replace_idx(&description, &idx);
158+
let cname = &ci.name;
159+
let description = str_utils::get_description(&ci.description);
153160
let text =
154161
format!("{addr} B CLUSTER {cname}{derived}: {description}");
155162
mmap.push(text);
@@ -166,26 +173,25 @@ fn get_registers(
166173
fn get_fields(register: &RegisterInfo, addr: &str, mmap: &mut Vec<String>) {
167174
if let Some(fields) = &register.fields {
168175
for f in fields {
169-
let description = str_utils::get_description(&f.description);
176+
let derived = derived_str(&f.derived_from);
170177
let access = svd_utils::access_with_brace(f.access);
171178
match f {
172179
Field::Single(f) => {
173-
let bit_offset = f.bit_range.offset;
174-
let bit_width = f.bit_range.width;
180+
let bit_offset = f.bit_offset();
181+
let bit_width = f.bit_width();
175182
let fname = &f.name;
176-
let derived = derived_str(&f.derived_from);
183+
let description = str_utils::get_description(&f.description);
177184
let text = format!(
178185
"{addr} C FIELD {bit_offset:02}w{bit_width:02} {fname}{derived}{access}: {description}"
179186
);
180187
mmap.push(text);
181188
}
182189
Field::Array(f, d) => {
183-
let derived = derived_str(&f.derived_from);
184-
for (i, idx) in d.indexes().enumerate() {
185-
let bit_offset = f.bit_range.offset + (i as u32) * d.dim_increment;
186-
let bit_width = f.bit_range.width;
187-
let fname = replace_idx(&f.name, &idx);
188-
let description = replace_idx(&description, &idx);
190+
for fi in svd::field::expand(f, d) {
191+
let bit_offset = fi.bit_offset();
192+
let bit_width = fi.bit_width();
193+
let fname = &fi.name;
194+
let description = str_utils::get_description(&fi.description);
189195
let text = format!(
190196
"{addr} C FIELD {bit_offset:02}w{bit_width:02} {fname}{derived}{access}: {description}"
191197
);

0 commit comments

Comments
 (0)