Skip to content

Commit 52a9b48

Browse files
authored
Merge pull request #749 from rust-embedded/array-proxy
array-proxy for disjoint arrays
2 parents effc1cb + 7dfb4fd commit 52a9b48

File tree

4 files changed

+37
-15
lines changed

4 files changed

+37
-15
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
77

88
## [Unreleased]
99

10+
- Use `ArrayProxy` for memory disjoined register arrays
1011
- Use `const fn` where allowed
1112

1213
## [v0.30.1] - 2023-10-01

src/generate/array_proxy.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
/// ensure that the memory really is backed by appropriate content.
88
///
99
/// Typically, this is used for accessing hardware registers.
10+
#[derive(Debug)]
1011
pub struct ArrayProxy<T, const COUNT: usize, const STRIDE: usize> {
1112
/// As well as providing a PhantomData, this field is non-public, and
1213
/// therefore ensures that code outside of this module can never create

src/generate/generic.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -431,12 +431,12 @@ impl<FI> BitReader<FI> {
431431
}
432432
/// Returns `true` if the bit is clear (0).
433433
#[inline(always)]
434-
pub fn bit_is_clear(&self) -> bool {
434+
pub const fn bit_is_clear(&self) -> bool {
435435
!self.bit()
436436
}
437437
/// Returns `true` if the bit is set (1).
438438
#[inline(always)]
439-
pub fn bit_is_set(&self) -> bool {
439+
pub const fn bit_is_set(&self) -> bool {
440440
self.bit()
441441
}
442442
}

src/generate/peripheral.rs

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,9 @@ struct Region {
329329
}
330330

331331
impl Region {
332+
fn size(&self) -> u32 {
333+
self.end - self.offset
334+
}
332335
fn shortest_ident(&self) -> Option<String> {
333336
let mut idents: Vec<_> = self
334337
.rbfs
@@ -490,12 +493,17 @@ impl FieldRegions {
490493
.binary_search_by_key(&new_region.offset, |r| r.offset);
491494
match idx {
492495
Ok(idx) => {
493-
bail!(
494-
"we shouldn't exist in the vec, but are at idx {} {:#?}\n{:#?}",
495-
idx,
496-
new_region,
497-
self.regions
498-
);
496+
if new_region.size() == 0 {
497+
// add ArrayProxy
498+
self.regions.insert(idx, new_region);
499+
} else {
500+
bail!(
501+
"we shouldn't exist in the vec, but are at idx {} {:#?}\n{:#?}",
502+
idx,
503+
new_region,
504+
self.regions
505+
);
506+
}
499507
}
500508
Err(idx) => self.regions.insert(idx, new_region),
501509
};
@@ -1185,6 +1193,8 @@ fn expand_register(
11851193
Register::Array(info, array_info) => {
11861194
let sequential_addresses = (array_info.dim == 1)
11871195
|| (register_size == array_info.dim_increment * BITS_PER_BYTE);
1196+
let disjoint_sequential_addresses = (array_info.dim == 1)
1197+
|| (register_size <= array_info.dim_increment * BITS_PER_BYTE);
11881198

11891199
let convert_list = match config.keep_list {
11901200
true => match &array_info.dim_name {
@@ -1208,20 +1218,22 @@ fn expand_register(
12081218
} else {
12091219
"".into()
12101220
};
1211-
let array_convertible = match derive_info {
1221+
let ac = match derive_info {
12121222
DeriveInfo::Implicit(_) => {
12131223
ty_name = util::replace_suffix(&info_name, &index);
1214-
sequential_addresses && convert_list && sequential_indexes_from0
1224+
convert_list && sequential_indexes_from0
12151225
}
12161226
DeriveInfo::Explicit(_) => {
12171227
ty_name = util::replace_suffix(&info_name, &index);
1218-
sequential_addresses && convert_list && sequential_indexes_from0
1228+
convert_list && sequential_indexes_from0
12191229
}
1220-
_ => sequential_addresses && convert_list,
1230+
_ => convert_list,
12211231
};
1232+
let array_convertible = ac && sequential_addresses;
1233+
let array_proxy_convertible = ac && disjoint_sequential_addresses;
12221234
let ty = name_to_ty(&ty_name);
12231235

1224-
if array_convertible {
1236+
if array_convertible || (array_proxy_convertible && config.const_generic) {
12251237
let accessors = if sequential_indexes_from0 {
12261238
Vec::new()
12271239
} else {
@@ -1247,14 +1259,22 @@ fn expand_register(
12471259
}
12481260
accessors
12491261
};
1250-
let array_ty = new_syn_array(ty, array_info.dim);
1262+
let array_ty = if array_convertible {
1263+
new_syn_array(ty, array_info.dim)
1264+
} else {
1265+
array_proxy_type(ty, array_info)
1266+
};
12511267
let syn_field =
12521268
new_syn_field(ty_name.to_snake_case_ident(Span::call_site()), array_ty);
12531269
register_expanded.push(RegisterBlockField {
12541270
syn_field,
12551271
description,
12561272
offset: info.address_offset,
1257-
size: register_size * array_info.dim,
1273+
size: if array_convertible {
1274+
register_size * array_info.dim
1275+
} else {
1276+
0
1277+
},
12581278
accessors,
12591279
});
12601280
} else {

0 commit comments

Comments
 (0)