Skip to content

Commit 968fbc5

Browse files
committed
Adding support for references to another peripheral
Handling "<PERIPHERAL>.<REGISTER>.<FIELD>.<ENUMERATEDVALUES>" format for the "derivedFrom" attribute in <enumeratedValues>.
1 parent 3af4e87 commit 968fbc5

File tree

2 files changed

+95
-10
lines changed

2 files changed

+95
-10
lines changed

src/generate.rs

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ pub fn device(d: &Device, items: &mut Vec<Tokens>) -> Result<()> {
6969
continue;
7070
}
7171

72-
::generate::peripheral(p, items, &d.defaults)?;
72+
::generate::peripheral(p, &d.peripherals, items, &d.defaults)?;
7373
}
7474

7575
Ok(())
@@ -235,6 +235,7 @@ pub fn interrupt(peripherals: &[Peripheral], items: &mut Vec<Tokens>) {
235235

236236
pub fn peripheral(
237237
p: &Peripheral,
238+
all_peripherals: &[Peripheral],
238239
items: &mut Vec<Tokens>,
239240
defaults: &Defaults,
240241
) -> Result<()> {
@@ -290,7 +291,7 @@ pub fn peripheral(
290291
mod_items.push(::generate::register_block(registers, defaults)?);
291292

292293
for register in registers {
293-
::generate::register(register, registers, p, defaults, &mut mod_items)?;
294+
::generate::register(register, registers, p, all_peripherals, defaults, &mut mod_items)?;
294295
}
295296

296297
let name_sc = Ident::new(&*p.name.to_sanitized_snake_case());
@@ -416,6 +417,7 @@ pub fn register(
416417
register: &Register,
417418
all_registers: &[Register],
418419
peripheral: &Peripheral,
420+
all_peripherals: &[Peripheral],
419421
defs: &Defaults,
420422
items: &mut Vec<Tokens>,
421423
) -> Result<()> {
@@ -572,6 +574,7 @@ pub fn register(
572574
register,
573575
all_registers,
574576
peripheral,
577+
all_peripherals,
575578
&rty,
576579
access,
577580
&mut mod_items,
@@ -623,6 +626,7 @@ pub fn fields(
623626
parent: &Register,
624627
all_registers: &[Register],
625628
peripheral: &Peripheral,
629+
all_peripherals: &[Peripheral],
626630
rty: &Ident,
627631
access: Access,
628632
mod_items: &mut Vec<Tokens>,
@@ -724,6 +728,7 @@ pub fn fields(
724728
parent,
725729
all_registers,
726730
peripheral,
731+
all_peripherals,
727732
Usage::Read,
728733
)? {
729734
struct Variant<'a> {
@@ -767,7 +772,19 @@ pub fn fields(
767772
let description =
768773
format!("Possible values of the field `{}`", f.name);
769774

770-
if let Some(ref register) = base.register {
775+
if let (Some(ref peripheral), Some(ref register)) = (base.peripheral, base.register) {
776+
let pmod_ = peripheral.to_sanitized_snake_case();
777+
let rmod_ = register.to_sanitized_snake_case();
778+
let pmod_ = Ident::new(&*pmod_);
779+
let rmod_ = Ident::new(&*rmod_);
780+
781+
mod_items.push(
782+
quote! {
783+
#[doc = #description]
784+
pub type #pc_r = ::#pmod_::#rmod_::#base_pc_r;
785+
},
786+
);
787+
} else if let Some(ref register) = base.register {
771788
let mod_ = register.to_sanitized_snake_case();
772789
let mod_ = Ident::new(&*mod_);
773790

@@ -1037,6 +1054,7 @@ pub fn fields(
10371054
parent,
10381055
all_registers,
10391056
peripheral,
1057+
all_peripherals,
10401058
Usage::Write,
10411059
)? {
10421060
struct Variant {
@@ -1058,7 +1076,24 @@ pub fn fields(
10581076
let pc = base.field.to_sanitized_pascal_case();
10591077
let base_pc_w = Ident::new(&*format!("{}W", pc));
10601078

1061-
if let Some(ref register) = base.register {
1079+
if let (Some(ref peripheral), Some(ref register)) = (base.peripheral, base.register) {
1080+
let pmod_ = peripheral.to_sanitized_snake_case();
1081+
let rmod_ = register.to_sanitized_snake_case();
1082+
let pmod_ = Ident::new(&*pmod_);
1083+
let rmod_ = Ident::new(&*rmod_);
1084+
1085+
mod_items.push(
1086+
quote! {
1087+
#[doc = #pc_w_doc]
1088+
pub type #pc_w =
1089+
::#pmod_::#rmod_::#base_pc_w;
1090+
},
1091+
);
1092+
1093+
quote! {
1094+
::#pmod_::#rmod_::#base_pc_w
1095+
}
1096+
} else if let Some(ref register) = base.register {
10621097
let mod_ = register.to_sanitized_snake_case();
10631098
let mod_ = Ident::new(&*mod_);
10641099

src/util.rs

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ pub fn unsuffixed_or_bool(n: u64, width: u32) -> Lit {
249249

250250
#[derive(Clone, Debug)]
251251
pub struct Base<'a> {
252+
pub peripheral: Option<&'a str>,
252253
pub register: Option<&'a str>,
253254
pub field: &'a str,
254255
}
@@ -260,27 +261,38 @@ pub fn lookup<'a>
260261
register: &'a Register,
261262
all_registers: &'a [Register],
262263
peripheral: &'a Peripheral,
264+
all_peripherals: &'a [Peripheral],
263265
usage: Usage,
264266
) -> Result<Option<(&'a EnumeratedValues, Option<Base<'a>>)>> {
265267
let evs = evs.iter()
266268
.map(
267269
|evs| if let Some(ref base) = evs.derived_from {
268270
let mut parts = base.split('.');
269271

270-
match (parts.next(), parts.next(), parts.next()) {
271-
(Some(base_register), Some(base_field), Some(base_evs)) => {
272+
match (parts.next(), parts.next(), parts.next(), parts.next()) {
273+
(Some(base_peripheral), Some(base_register), Some(base_field), Some(base_evs)) => {
274+
lookup_in_peripherals(
275+
base_peripheral,
276+
base_register,
277+
base_field,
278+
base_evs,
279+
all_peripherals,
280+
)
281+
}
282+
(Some(base_register), Some(base_field), Some(base_evs), None) => {
272283
lookup_in_peripheral(
284+
None,
273285
base_register,
274286
base_field,
275287
base_evs,
276288
all_registers,
277289
peripheral,
278290
)
279291
}
280-
(Some(base_field), Some(base_evs), None) => {
292+
(Some(base_field), Some(base_evs), None, None) => {
281293
lookup_in_fields(base_evs, base_field, fields, register)
282294
}
283-
(Some(base_evs), None, None) => {
295+
(Some(base_evs), None, None, None) => {
284296
lookup_in_register(base_evs, register)
285297
}
286298
_ => unreachable!(),
@@ -307,7 +319,7 @@ fn lookup_in_fields<'f>(
307319
register: &Register,
308320
) -> Result<(&'f EnumeratedValues, Option<Base<'f>>)> {
309321
if let Some(base_field) = fields.iter().find(|f| f.name == base_field) {
310-
return lookup_in_field(base_evs, None, base_field);
322+
return lookup_in_field(base_evs, None, None, base_field);
311323
} else {
312324
Err(
313325
format!(
@@ -321,6 +333,7 @@ fn lookup_in_fields<'f>(
321333

322334
fn lookup_in_peripheral<'p>
323335
(
336+
base_peripheral: Option<&'p str>,
324337
base_register: &'p str,
325338
base_field: &str,
326339
base_evs: &str,
@@ -339,7 +352,7 @@ fn lookup_in_peripheral<'p>
339352
.unwrap_or(&[])
340353
.iter()
341354
.find(|f| f.name == base_field) {
342-
lookup_in_field(base_evs, Some(base_register), field)
355+
lookup_in_field(base_evs, Some(base_register), base_peripheral, field)
343356
} else {
344357
Err(
345358
format!(
@@ -363,6 +376,7 @@ fn lookup_in_peripheral<'p>
363376
fn lookup_in_field<'f>(
364377
base_evs: &str,
365378
base_register: Option<&'f str>,
379+
base_peripheral: Option<&'f str>,
366380
field: &'f Field,
367381
) -> Result<(&'f EnumeratedValues, Option<Base<'f>>)> {
368382
for evs in &field.enumerated_values {
@@ -373,6 +387,7 @@ fn lookup_in_field<'f>(
373387
Base {
374388
field: &field.name,
375389
register: base_register,
390+
peripheral: base_peripheral,
376391
},
377392
))),
378393
);
@@ -416,6 +431,7 @@ fn lookup_in_register<'r>
416431
Base {
417432
field: field,
418433
register: None,
434+
peripheral: None
419435
},
420436
)),
421437
);
@@ -437,6 +453,40 @@ fn lookup_in_register<'r>
437453
}
438454
}
439455

456+
fn lookup_in_peripherals<'p>
457+
(
458+
base_peripheral: &'p str,
459+
base_register: &'p str,
460+
base_field: &str,
461+
base_evs: &str,
462+
all_peripherals: &'p [Peripheral],
463+
) -> Result<(&'p EnumeratedValues, Option<Base<'p>>)> {
464+
if let Some(peripheral) = all_peripherals
465+
.iter()
466+
.find(|p| { p.name == base_peripheral }) {
467+
let all_registers = peripheral.registers
468+
.as_ref()
469+
.map(|x| x.as_ref())
470+
.unwrap_or(&[][..]);
471+
lookup_in_peripheral(
472+
Some(base_peripheral),
473+
base_register,
474+
base_field,
475+
base_evs,
476+
all_registers,
477+
peripheral
478+
)
479+
} else {
480+
Err(
481+
format!(
482+
"No peripheral {}",
483+
base_peripheral
484+
),
485+
)?
486+
}
487+
}
488+
489+
440490
pub trait U32Ext {
441491
fn to_ty(&self) -> Result<Ident>;
442492
fn to_ty_width(&self) -> Result<u32>;

0 commit comments

Comments
 (0)