Skip to content

Commit ab251bf

Browse files
bors[bot]wezEmilgardis
committed
Merge #192
192: Emit unions for overlapping/overloaded registers r=Emilgardis a=wez I want to get a complete working build for ATSAMD21 (rust-embedded/wg#61) so I'm taking a stab at that. * Introduced a `FieldRegion` helper to reason about overlapping regions * If overlaps are detected, a `union` container is emitted * If the only item in a `RegisterBlock` is a union, that `RegisterBlock` is emitted as a union * Otherwise: we generate a name for the union field by either taking the shortest common prefix of the union's alternates or the shortest register name (depending on type name conflicts). If that doesn't work just pick an artificial name like `u1`. * If the starting address offset of elements in a union are not all the same, we don't have a way to emit padding for them today. We will emit a warning (and bad code) in that case (example below). The one example of this I see in ATSAMD21 is due to missing `derivedFrom` support for registers; we're currently generating bad code for these anyway. I have resolved in another branch that I'll turn into a PR once this one is landed. ``` WARNING: field Some(Ident("pmux1_1")) has different offset 177 than its union container 176 WARNING: field Some(Ident("pmux1_2")) has different offset 178 than its union container 176 ``` Examples: ``` #[doc = "Real-Time Counter"] pub mod rtc { #[doc = r" Register block"] #[repr(C)] pub union RegisterBlock { #[doc = "0x00 - Clock/Calendar with Alarm"] pub mode2: MODE2, #[doc = "0x00 - 16-bit Counter with Two 16-bit Compares"] pub mode1: MODE1, #[doc = "0x00 - 32-bit Counter with Single 32-bit Compare"] pub mode0: MODE0, } ``` ``` #[doc = r" Register block"] #[repr(C)] pub struct USART { #[doc = "0x00 - USART Control A"] pub ctrla: self::usart::CTRLA, #[doc = "0x04 - USART Control B"] pub ctrlb: self::usart::CTRLB, _reserved2: [u8; 4usize], #[doc = "USART Baud Rate"] pub baud: baud_union, ... } #[doc = "USART Baud Rate"] #[repr(C)] pub union baud_union { #[doc = "0x0c - USART Baud Rate"] pub baud_usartfp_mode: self::usart::BAUD_USARTFP_MODE, #[doc = "0x0c - USART Baud Rate"] pub baud_fracfp_mode: self::usart::BAUD_FRACFP_MODE, #[doc = "0x0c - USART Baud Rate"] pub baud_frac_mode: self::usart::BAUD_FRAC_MODE, #[doc = "0x0c - USART Baud Rate"] pub baud: self::usart::BAUD, } ``` Refs: #191 #16 Co-authored-by: Wez Furlong <[email protected]> Co-authored-by: Emil Gardström <[email protected]>
2 parents cc42c11 + f676846 commit ab251bf

File tree

4 files changed

+397
-27
lines changed

4 files changed

+397
-27
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
[._]*.sw[a-p]
12
*.org
23
*.rs.bk
34
*.svd

src/generate/device.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use Target;
99
use generate::{interrupt, peripheral};
1010

1111
/// Whole device generation
12-
pub fn render(d: &Device, target: &Target) -> Result<Vec<Tokens>> {
12+
pub fn render(d: &Device, target: &Target, nightly: bool) -> Result<Vec<Tokens>> {
1313
let mut out = vec![];
1414

1515
let doc = format!(
@@ -46,6 +46,12 @@ pub fn render(d: &Device, target: &Target) -> Result<Vec<Tokens>> {
4646
#![no_std]
4747
});
4848

49+
if nightly {
50+
out.push(quote! {
51+
#![feature(untagged_unions)]
52+
});
53+
}
54+
4955
match *target {
5056
Target::CortexM => {
5157
out.push(quote! {
@@ -127,7 +133,7 @@ pub fn render(d: &Device, target: &Target) -> Result<Vec<Tokens>> {
127133
}
128134

129135

130-
out.extend(peripheral::render(p, &d.peripherals, &d.defaults)?);
136+
out.extend(peripheral::render(p, &d.peripherals, &d.defaults, nightly)?);
131137

132138
if p.registers
133139
.as_ref()

0 commit comments

Comments
 (0)