aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Cully <bjc@kublai.com>2019-07-30 09:48:19 -0400
committerBrian Cully <bjc@kublai.com>2019-07-30 09:48:19 -0400
commitd94d88faa9c0e1a5c18b21962964dfdda3011a1d (patch)
treec6b55724f512b0ca221ccf5925006c7e568a2991
parentc20e974373e9daeb81278794bc73033b88eb756c (diff)
downloadsamd21-demo-d94d88faa9c0e1a5c18b21962964dfdda3011a1d.tar.gz
samd21-demo-d94d88faa9c0e1a5c18b21962964dfdda3011a1d.zip
Use `repr(packed)` on pipe descriptors structure.
Ensure offsets and sizes are correct with tests.
-rw-r--r--usbh/src/pipe.rs80
-rw-r--r--usbh/src/pipe/addr.rs2
-rw-r--r--usbh/src/pipe/ctrl_pipe.rs2
-rw-r--r--usbh/src/pipe/ext_reg.rs2
-rw-r--r--usbh/src/pipe/pck_size.rs2
-rw-r--r--usbh/src/pipe/status_bk.rs2
-rw-r--r--usbh/src/pipe/status_pipe.rs52
7 files changed, 107 insertions, 35 deletions
diff --git a/usbh/src/pipe.rs b/usbh/src/pipe.rs
index c33a3a2..cd89eb3 100644
--- a/usbh/src/pipe.rs
+++ b/usbh/src/pipe.rs
@@ -608,17 +608,17 @@ impl PipeDesc {
}
#[derive(Clone, Copy, Debug)]
-#[repr(C)]
+#[repr(C, packed)]
// 16 bytes per bank.
pub(crate) struct BankDesc {
pub addr: Addr,
pub pcksize: PckSize,
pub extreg: ExtReg,
pub status_bk: StatusBk,
+ _reserved0: u8,
pub ctrl_pipe: CtrlPipe,
pub status_pipe: StatusPipe,
-
- _reserved: u8,
+ _reserved1: u8,
}
impl BankDesc {
@@ -628,9 +628,81 @@ impl BankDesc {
pcksize: PckSize::from(0),
extreg: ExtReg::from(0),
status_bk: StatusBk::from(0),
+ _reserved0: 0,
ctrl_pipe: CtrlPipe::from(0),
status_pipe: StatusPipe::from(0),
- _reserved: 0,
+ _reserved1: 0,
}
}
}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ #[test]
+ fn bank_desc_sizes() {
+ assert_eq!(core::mem::size_of::<Addr>(), 4, "Addr register size.");
+ assert_eq!(core::mem::size_of::<PckSize>(), 4, "PckSize register size.");
+ assert_eq!(core::mem::size_of::<ExtReg>(), 2, "ExtReg register size.");
+ assert_eq!(
+ core::mem::size_of::<StatusBk>(),
+ 1,
+ "StatusBk register size."
+ );
+ assert_eq!(
+ core::mem::size_of::<CtrlPipe>(),
+ 2,
+ "CtrlPipe register size."
+ );
+ assert_eq!(
+ core::mem::size_of::<StatusPipe>(),
+ 1,
+ "StatusPipe register size."
+ );
+
+ // addr at 0x00 for 4
+ // pcksize at 0x04 for 4
+ // extreg at 0x08 for 2
+ // status_bk at 0x0a for 2
+ // ctrl_pipe at 0x0c for 2
+ // status_pipe at 0x0e for 1
+ assert_eq!(
+ core::mem::size_of::<BankDesc>(),
+ 16,
+ "Bank descriptor size."
+ );
+ }
+
+ #[test]
+ fn bank_desc_offsets() {
+ let bd = BankDesc::new();
+ let base = &bd as *const _ as usize;
+
+ assert_offset("Addr", &bd.addr, base, 0x00);
+ assert_offset("PckSize", &bd.pcksize, base, 0x04);
+ assert_offset("ExtReg", &bd.extreg, base, 0x08);
+ assert_offset("StatusBk", &bd.status_bk, base, 0x0a);
+ assert_offset("CtrlPipe", &bd.ctrl_pipe, base, 0x0c);
+ assert_offset("StatusPipe", &bd.status_pipe, base, 0x0e);
+ }
+
+ #[test]
+ fn pipe_desc_size() {
+ assert_eq!(core::mem::size_of::<PipeDesc>(), 32);
+ }
+
+ #[test]
+ fn pipe_desc_offsets() {
+ let pd = PipeDesc::new();
+ let base = &pd as *const _ as usize;
+
+ assert_offset("Bank0", &pd.bank0, base, 0x00);
+ assert_offset("Bank1", &pd.bank1, base, 0x10);
+ }
+
+ fn assert_offset<T>(name: &str, field: &T, base: usize, offset: usize) {
+ let ptr = field as *const _ as usize;
+ assert_eq!(ptr - base, offset, "{} register offset.", name);
+ }
+}
diff --git a/usbh/src/pipe/addr.rs b/usbh/src/pipe/addr.rs
index 81cef5d..aa26048 100644
--- a/usbh/src/pipe/addr.rs
+++ b/usbh/src/pipe/addr.rs
@@ -5,7 +5,7 @@
/// Reset: 0xxxxxxxxx
/// Property: NA
#[derive(Clone, Copy, Debug)]
-#[repr(C)]
+#[repr(C, packed)]
pub(crate) struct Addr(u32);
pub(crate) struct R {
diff --git a/usbh/src/pipe/ctrl_pipe.rs b/usbh/src/pipe/ctrl_pipe.rs
index 63390df..179b615 100644
--- a/usbh/src/pipe/ctrl_pipe.rs
+++ b/usbh/src/pipe/ctrl_pipe.rs
@@ -4,7 +4,7 @@
/// Reset: 0xXXXX
/// Property: PAC Write-Protection, Write-Synchronized, Read-Synchronized
#[derive(Clone, Copy, Debug)]
-#[repr(C)]
+#[repr(C, packed)]
pub(crate) struct CtrlPipe(u16);
pub(crate) struct R {
diff --git a/usbh/src/pipe/ext_reg.rs b/usbh/src/pipe/ext_reg.rs
index 023ce9f..9778f1b 100644
--- a/usbh/src/pipe/ext_reg.rs
+++ b/usbh/src/pipe/ext_reg.rs
@@ -5,7 +5,7 @@
/// Reset: 0xxxxxxxx
/// Property: NA
#[derive(Clone, Copy, Debug)]
-#[repr(C)]
+#[repr(C, packed)]
pub(crate) struct ExtReg(u16);
pub(crate) struct R {
diff --git a/usbh/src/pipe/pck_size.rs b/usbh/src/pipe/pck_size.rs
index 9648381..acc499f 100644
--- a/usbh/src/pipe/pck_size.rs
+++ b/usbh/src/pipe/pck_size.rs
@@ -5,7 +5,7 @@
/// Reset: 0xxxxxxxxx
/// Property: NA
#[derive(Clone, Copy, Debug)]
-#[repr(C)]
+#[repr(C, packed)]
pub(crate) struct PckSize(u32);
pub(crate) struct R {
diff --git a/usbh/src/pipe/status_bk.rs b/usbh/src/pipe/status_bk.rs
index 4ddb420..489fc62 100644
--- a/usbh/src/pipe/status_bk.rs
+++ b/usbh/src/pipe/status_bk.rs
@@ -5,7 +5,7 @@
/// Reset: 0xxxxxxx
/// Property: NA
#[derive(Clone, Copy, Debug)]
-#[repr(C)]
+#[repr(C, packed)]
pub(crate) struct StatusBk(u8);
pub(crate) struct R {
diff --git a/usbh/src/pipe/status_pipe.rs b/usbh/src/pipe/status_pipe.rs
index 4f8eb41..be135c5 100644
--- a/usbh/src/pipe/status_pipe.rs
+++ b/usbh/src/pipe/status_pipe.rs
@@ -4,14 +4,14 @@
/// Reset: 0xxxxxx
/// Property: PAC Write-Protection, Write-Synchronized, Read-Synchronized
#[derive(Clone, Copy, Debug)]
-#[repr(C)]
-pub(crate) struct StatusPipe(u16);
+#[repr(C, packed)]
+pub(crate) struct StatusPipe(u8);
pub(crate) struct R {
- bits: u16,
+ bits: u8,
}
pub(crate) struct W {
- bits: u16,
+ bits: u8,
}
impl StatusPipe {
@@ -29,22 +29,22 @@ impl StatusPipe {
}
}
-impl From<u16> for StatusPipe {
- fn from(v: u16) -> Self {
+impl From<u8> for StatusPipe {
+ fn from(v: u8) -> Self {
Self(v)
}
}
impl R {
/// Value in raw bits.
- pub fn bits(&self) -> u16 {
+ pub fn bits(&self) -> u8 {
self.bits
}
pub fn ercnt(&self) -> ErCntR {
let bits = {
const POS: u8 = 5;
- const MASK: u16 = 0x7;
+ const MASK: u8 = 0x7;
((self.bits >> POS) & MASK) as u8
};
@@ -54,7 +54,7 @@ impl R {
pub fn crc16er(&self) -> CRC16ErR {
let bits = {
const POS: u8 = 4;
- const MASK: u16 = 1;
+ const MASK: u8 = 1;
((self.bits >> POS) & MASK) == 1
};
@@ -64,7 +64,7 @@ impl R {
pub fn touter(&self) -> TOutErrR {
let bits = {
const POS: u8 = 3;
- const MASK: u16 = 1;
+ const MASK: u8 = 1;
((self.bits >> POS) & MASK) == 1
};
@@ -75,7 +75,7 @@ impl R {
pub fn pider(&self) -> PIDErR {
let bits = {
const POS: u8 = 2;
- const MASK: u16 = 1;
+ const MASK: u8 = 1;
((self.bits >> POS) & MASK) == 1
};
@@ -86,7 +86,7 @@ impl R {
pub fn dapider(&self) -> DaPIDErR {
let bits = {
const POS: u8 = 1;
- const MASK: u16 = 1;
+ const MASK: u8 = 1;
((self.bits >> POS) & MASK) == 1
};
@@ -97,7 +97,7 @@ impl R {
pub fn dtgler(&self) -> DTglErR {
let bits = {
const POS: u8 = 0;
- const MASK: u16 = 1;
+ const MASK: u8 = 1;
((self.bits >> POS) & MASK) == 1
};
@@ -222,7 +222,7 @@ impl DTglErR {
impl W {
/// Write raw bits.
- pub unsafe fn bits(&mut self, v: u16) -> &mut Self {
+ pub unsafe fn bits(&mut self, v: u8) -> &mut Self {
self.bits = v;
self
}
@@ -262,8 +262,8 @@ impl<'a> ErCntW<'a> {
pub unsafe fn bits(self, v: u8) -> &'a mut W {
const POS: u8 = 5;
const MASK: u8 = 0x7;
- self.w.bits &= !((MASK as u16) << POS);
- self.w.bits |= ((v & MASK) as u16) << POS;
+ self.w.bits &= !((MASK as u8) << POS);
+ self.w.bits |= ((v & MASK) as u8) << POS;
self.w
}
@@ -285,8 +285,8 @@ impl<'a> CRC16ErW<'a> {
pub fn bit(self, v: bool) -> &'a mut W {
const POS: u8 = 4;
const MASK: bool = true;
- self.w.bits &= !((MASK as u16) << POS);
- self.w.bits |= ((v & MASK) as u16) << POS;
+ self.w.bits &= !((MASK as u8) << POS);
+ self.w.bits |= ((v & MASK) as u8) << POS;
self.w
}
@@ -312,8 +312,8 @@ impl<'a> TOutErW<'a> {
pub fn bit(self, v: bool) -> &'a mut W {
const POS: u8 = 3;
const MASK: bool = true;
- self.w.bits &= !((MASK as u16) << POS);
- self.w.bits |= ((v & MASK) as u16) << POS;
+ self.w.bits &= !((MASK as u8) << POS);
+ self.w.bits |= ((v & MASK) as u8) << POS;
self.w
}
@@ -339,8 +339,8 @@ impl<'a> PIDErW<'a> {
pub fn bit(self, v: bool) -> &'a mut W {
const POS: u8 = 2;
const MASK: bool = true;
- self.w.bits &= !((MASK as u16) << POS);
- self.w.bits |= ((v & MASK) as u16) << POS;
+ self.w.bits &= !((MASK as u8) << POS);
+ self.w.bits |= ((v & MASK) as u8) << POS;
self.w
}
@@ -366,8 +366,8 @@ impl<'a> DaPIDErW<'a> {
pub fn bit(self, v: bool) -> &'a mut W {
const POS: u8 = 1;
const MASK: bool = true;
- self.w.bits &= !((MASK as u16) << POS);
- self.w.bits |= ((v & MASK) as u16) << POS;
+ self.w.bits &= !((MASK as u8) << POS);
+ self.w.bits |= ((v & MASK) as u8) << POS;
self.w
}
@@ -392,8 +392,8 @@ impl<'a> DTglErW<'a> {
pub fn bit(self, v: bool) -> &'a mut W {
const POS: u8 = 0;
const MASK: bool = true;
- self.w.bits &= !((MASK as u16) << POS);
- self.w.bits |= ((v & MASK) as u16) << POS;
+ self.w.bits &= !((MASK as u8) << POS);
+ self.w.bits |= ((v & MASK) as u8) << POS;
self.w
}