Skip to content

Commit 88c3aca

Browse files
bors[bot]burrbull
andauthored
Merge #106
106: Add support for modifiedWriteValues & readAction r=adamgreig a=burrbull Co-authored-by: Andrey Zgarbul <[email protected]>
2 parents ed4ed40 + 66ca3d0 commit 88c3aca

File tree

3 files changed

+158
-22
lines changed

3 files changed

+158
-22
lines changed

CHANGELOG-rust.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ This changelog tracks the Rust `svdtools` project. See
55

66
## [Unreleased]
77

8+
* Add support for `modifiedWriteValues` & `readAction` for fields
9+
810
## [v0.2.2] 2022-04-23
911

1012
* Use `svd-encoder` 0.13.2

src/patch/register.rs

Lines changed: 83 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use anyhow::{anyhow, Context};
22
use svd_parser::svd::{
3-
BitRange, DimElement, EnumeratedValues, Field, FieldInfo, Register, RegisterInfo, Usage,
4-
WriteConstraint, WriteConstraintRange,
3+
BitRange, DimElement, EnumeratedValues, Field, FieldInfo, ModifiedWriteValues, ReadAction,
4+
Register, RegisterInfo, Usage, WriteConstraint, WriteConstraintRange,
55
};
66
use yaml_rust::{yaml::Hash, Yaml};
77

@@ -58,6 +58,12 @@ pub trait RegisterExt {
5858
usage: Usage,
5959
) -> PatchResult;
6060

61+
/// Set readAction for field
62+
fn set_field_read_action(&mut self, fspec: &str, action: ReadAction);
63+
64+
/// Set modifiedWriteValues for field
65+
fn set_field_modified_write_values(&mut self, fspec: &str, mwv: ModifiedWriteValues);
66+
6167
/// Add a writeConstraint range given by field to all fspec in rtag
6268
fn process_field_range(&mut self, pname: &str, fspec: &str, fmod: &[Yaml]) -> PatchResult;
6369

@@ -452,21 +458,67 @@ impl RegisterExt for Register {
452458
}
453459

454460
fn process_field(&mut self, pname: &str, fspec: &str, fmod: &Yaml) -> PatchResult {
461+
const READ_KEYS: [&str; 5] = ["_read", "_RM", "_RS", "_RC", "_RME"];
462+
const READ_VALS: [Option<ReadAction>; 5] = [
463+
None,
464+
Some(ReadAction::Modify),
465+
Some(ReadAction::Set),
466+
Some(ReadAction::Clear),
467+
Some(ReadAction::ModifyExternal),
468+
];
469+
const WRITE_KEYS: [&str; 10] = [
470+
"_write", "_WM", "_WS", "_WC", "_W1S", "_W0C", "_W1C", "_W0S", "_W1T", "_W0T",
471+
];
472+
const WRITE_VALS: [Option<ModifiedWriteValues>; 10] = [
473+
None,
474+
Some(ModifiedWriteValues::Modify),
475+
Some(ModifiedWriteValues::Set),
476+
Some(ModifiedWriteValues::Clear),
477+
Some(ModifiedWriteValues::OneToSet),
478+
Some(ModifiedWriteValues::ZeroToClear),
479+
Some(ModifiedWriteValues::OneToClear),
480+
Some(ModifiedWriteValues::ZeroToSet),
481+
Some(ModifiedWriteValues::OneToToggle),
482+
Some(ModifiedWriteValues::ZeroToToggle),
483+
];
455484
match fmod {
456485
Yaml::Hash(fmod) => {
457-
let is_read = fmod.get_hash("_read")?;
458-
let is_write = fmod.get_hash("_write")?;
459-
if is_read.is_none() && is_write.is_none() {
486+
let is_read = READ_KEYS
487+
.iter()
488+
.any(|key| fmod.contains_key(&key.to_yaml()));
489+
let is_write = WRITE_KEYS
490+
.iter()
491+
.any(|key| fmod.contains_key(&key.to_yaml()));
492+
if !is_read && !is_write {
460493
self.process_field_enum(pname, fspec, fmod, Usage::ReadWrite)
461494
.with_context(|| "Adding read-write enumeratedValues")?;
462495
} else {
463-
if let Some(fmod) = is_read {
464-
self.process_field_enum(pname, fspec, fmod, Usage::Read)
465-
.with_context(|| "Adding read-only enumeratedValues")?;
496+
if is_read {
497+
for (key, action) in READ_KEYS.into_iter().zip(READ_VALS.into_iter()) {
498+
if let Some(fmod) = fmod.get_hash(key)? {
499+
if !fmod.is_empty() {
500+
self.process_field_enum(pname, fspec, fmod, Usage::Read)
501+
.with_context(|| "Adding read-only enumeratedValues")?;
502+
}
503+
if let Some(action) = action {
504+
self.set_field_read_action(fspec, action);
505+
}
506+
break;
507+
}
508+
}
466509
}
467-
if let Some(fmod) = is_write {
468-
self.process_field_enum(pname, fspec, fmod, Usage::Write)
469-
.with_context(|| "Adding write-only enumeratedValues")?;
510+
if is_write {
511+
for (key, mwv) in WRITE_KEYS.into_iter().zip(WRITE_VALS.into_iter()) {
512+
if let Some(fmod) = fmod.get_hash(key)? {
513+
if !fmod.is_empty() {
514+
self.process_field_enum(pname, fspec, fmod, Usage::Write)
515+
.with_context(|| "Adding write-only enumeratedValues")?;
516+
}
517+
if let Some(mwv) = mwv {
518+
self.set_field_modified_write_values(fspec, mwv);
519+
}
520+
}
521+
}
470522
}
471523
}
472524
}
@@ -479,6 +531,26 @@ impl RegisterExt for Register {
479531
Ok(())
480532
}
481533

534+
fn set_field_read_action(&mut self, fspec: &str, action: ReadAction) {
535+
for ftag in self.iter_fields(fspec) {
536+
ftag.read_action = if action == ReadAction::Modify {
537+
None
538+
} else {
539+
Some(action)
540+
};
541+
}
542+
}
543+
544+
fn set_field_modified_write_values(&mut self, fspec: &str, mwv: ModifiedWriteValues) {
545+
for ftag in self.iter_fields(fspec) {
546+
ftag.modified_write_values = if mwv == ModifiedWriteValues::Modify {
547+
None
548+
} else {
549+
Some(mwv)
550+
};
551+
}
552+
}
553+
482554
fn process_field_enum(
483555
&mut self,
484556
pname: &str,

svdtools/patch.py

Lines changed: 73 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,21 +1324,83 @@ def split_fields(self, fspec, fsplit):
13241324
ET.SubElement(fnew, "bitOffset").text = str(bitoffset + i)
13251325
ET.SubElement(fnew, "bitWidth").text = str(1)
13261326

1327-
def process_field(self, pname, fspec, field):
1327+
def process_field(self, pname, fspec, fmod):
13281328
"""Work through a field, handling either an enum or a range."""
1329-
if isinstance(field, dict):
1330-
usages = ("_read", "_write")
1329+
if isinstance(fmod, dict):
1330+
read_keys = ["_read", "_RM", "_RS", "_RC", "_RME"]
1331+
read_vals = ["", "modify", "set", "clear", "modifyExternal"]
1332+
write_keys = [
1333+
"_write",
1334+
"_WM",
1335+
"_WS",
1336+
"_WC",
1337+
"_W1S",
1338+
"_W0C",
1339+
"_W1C",
1340+
"_W0S",
1341+
"_W1T",
1342+
"_W0T",
1343+
]
1344+
write_vals = [
1345+
"",
1346+
"modify",
1347+
"set",
1348+
"clear",
1349+
"oneToSet",
1350+
"zeroToClear",
1351+
"oneToClear",
1352+
"zeroToSet",
1353+
"oneToToggle",
1354+
"zeroToToggle",
1355+
]
1356+
is_read = any(key in fmod for key in read_keys)
1357+
is_write = any(key in fmod for key in write_keys)
1358+
if not is_read and not is_write:
1359+
self.process_field_enum(pname, fspec, fmod)
1360+
else:
1361+
if is_read:
1362+
for key, action in zip(read_keys, read_vals):
1363+
if key in fmod:
1364+
mod = fmod[key]
1365+
if mod:
1366+
self.process_field_enum(pname, fspec, mod, usage="read")
1367+
if action:
1368+
self.set_field_read_action(fspec, action)
1369+
break
1370+
if is_write:
1371+
for key, mwv in zip(write_keys, write_vals):
1372+
if key in fmod:
1373+
mod = fmod[key]
1374+
if mod:
1375+
self.process_field_enum(
1376+
pname, fspec, mod, usage="write"
1377+
)
1378+
if mwv:
1379+
self.set_field_modified_write_values(fspec, mwv)
1380+
break
13311381

1332-
if not any(u in field for u in usages):
1333-
self.process_field_enum(pname, fspec, field)
1382+
elif isinstance(fmod, list) and len(fmod) == 2:
1383+
self.process_field_range(pname, fspec, fmod)
13341384

1335-
for usage in (u for u in usages if u in field):
1336-
self.process_field_enum(
1337-
pname, fspec, field[usage], usage=usage.replace("_", "")
1338-
)
1385+
def set_field_read_action(self, fspec, action):
1386+
for ftag in self.iter_fields(fspec):
1387+
tag = ftag.find("readAction")
1388+
if tag is None:
1389+
tag = ET.SubElement(ftag, "readAction")
1390+
elif action == "modify":
1391+
ftag.remove(tag)
1392+
return
1393+
tag.text = action
13391394

1340-
elif isinstance(field, list) and len(field) == 2:
1341-
self.process_field_range(pname, fspec, field)
1395+
def set_field_modified_write_values(self, fspec, mwv):
1396+
for ftag in self.iter_fields(fspec):
1397+
tag = ftag.find("modifiedWriteValues")
1398+
if tag is None:
1399+
tag = ET.SubElement(ftag, "modifiedWriteValues")
1400+
elif mwv == "modify":
1401+
ftag.remove(tag)
1402+
return
1403+
tag.text = mwv
13421404

13431405
def process_field_enum(self, pname, fspec, field, usage="read-write"):
13441406
"""Add an enumeratedValues given by field to all fspec in rtag."""

0 commit comments

Comments
 (0)