From d94d88faa9c0e1a5c18b21962964dfdda3011a1d Mon Sep 17 00:00:00 2001 From: Brian Cully Date: Tue, 30 Jul 2019 09:48:19 -0400 Subject: Use `repr(packed)` on pipe descriptors structure. Ensure offsets and sizes are correct with tests. --- usbh/src/pipe.rs | 80 +++++++++++++++++++++++++++++++++++++++++--- usbh/src/pipe/addr.rs | 2 +- usbh/src/pipe/ctrl_pipe.rs | 2 +- usbh/src/pipe/ext_reg.rs | 2 +- usbh/src/pipe/pck_size.rs | 2 +- usbh/src/pipe/status_bk.rs | 2 +- usbh/src/pipe/status_pipe.rs | 52 ++++++++++++++-------------- 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::(), 4, "Addr register size."); + assert_eq!(core::mem::size_of::(), 4, "PckSize register size."); + assert_eq!(core::mem::size_of::(), 2, "ExtReg register size."); + assert_eq!( + core::mem::size_of::(), + 1, + "StatusBk register size." + ); + assert_eq!( + core::mem::size_of::(), + 2, + "CtrlPipe register size." + ); + assert_eq!( + core::mem::size_of::(), + 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::(), + 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::(), 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(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 for StatusPipe { - fn from(v: u16) -> Self { +impl From 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 } -- cgit v1.2.3