aboutsummaryrefslogtreecommitdiffstats
path: root/src/pipe/addr.rs
diff options
context:
space:
mode:
authorBrian Cully <bjc@kublai.com>2019-09-23 12:45:09 -0400
committerBrian Cully <bjc@kublai.com>2019-09-24 10:55:25 -0400
commitfcc6951c707144ba423b81e03bc2f34b6cfa7286 (patch)
tree574f64eb11e23920343137e352eb1279f1940a5d /src/pipe/addr.rs
parent77d1fdf044326cfb039728bf94a998f1dd1e8d1e (diff)
downloadatsamd-usb-host-fcc6951c707144ba423b81e03bc2f34b6cfa7286.tar.gz
atsamd-usb-host-fcc6951c707144ba423b81e03bc2f34b6cfa7286.zip
Mark pipe descriptor register memory as volatile.
Most of the values in the descriptor memory can be modified by the hardware, so we need to tell Rust that. Also, refactor the common register setup code into `register.rs`.
Diffstat (limited to 'src/pipe/addr.rs')
-rw-r--r--src/pipe/addr.rs89
1 files changed, 18 insertions, 71 deletions
diff --git a/src/pipe/addr.rs b/src/pipe/addr.rs
index d71ee2d..81b6bec 100644
--- a/src/pipe/addr.rs
+++ b/src/pipe/addr.rs
@@ -1,60 +1,29 @@
+use super::register::{Readable, Register, Writable, R as GenR, W as GenW};
+
/// § 32.8.7.2
/// Address of the Data Buffer.
///
/// Offset: 0x00 & 0x10
/// Reset: 0xxxxxxxxx
/// Property: NA
-#[derive(Clone, Copy, Debug)]
-#[repr(C, packed)]
-pub struct Addr(u32);
-
-pub struct R {
- bits: u32,
-}
-
-pub struct W {
- bits: u32,
-}
-
-impl Addr {
- pub fn read(self) -> R {
- R { bits: self.0 }
- }
-
- pub fn write<F>(&mut self, f: F)
- where
- F: FnOnce(&mut W) -> &mut W,
- {
- let mut w = W { bits: self.0 };
- f(&mut w);
- self.0 = w.bits;
- }
+pub type Addr = Register<u32, _Addr>;
+impl Readable for Addr {}
+impl Writable for Addr {}
- pub fn modify<F>(&mut self, f: F)
- where
- for<'w> F: FnOnce(&R, &'w mut W) -> &'w mut W,
- {
- let r = R { bits: self.0 };
- let mut w = W { bits: self.0 };
- f(&r, &mut w);
- self.0 = w.bits;
- }
-}
+pub type R = GenR<u32, Addr>;
+pub type W = GenW<u32, Addr>;
-impl From<u32> for Addr {
- fn from(v: u32) -> Self {
- Self(v)
- }
-}
+pub struct _Addr;
impl R {
- /// Value in raw bits.
- pub fn bits(&self) -> u32 {
- self.bits
+ pub fn addr(&self) -> AddrR {
+ AddrR::new(self.bits)
}
+}
- pub fn addr(&self) -> AddrR {
- AddrR(self.bits)
+impl W {
+ pub fn addr(&mut self) -> AddrW {
+ AddrW { w: self }
}
}
@@ -63,36 +32,14 @@ impl R {
/// These bits define the data pointer address as an absolute double
/// word address in RAM. The two least significant bits must be zero
/// to ensure the descriptor is 32-bit aligned.
-pub struct AddrR(u32);
-impl AddrR {
- pub fn bits(&self) -> u32 {
- self.0
- }
-}
-
-impl W {
- /// Write raw bits.
- pub unsafe fn bits(&mut self, v: u32) -> &mut Self {
- self.bits = v;
- self
- }
-
- pub fn addr(&mut self) -> AddrW {
- AddrW { w: self }
- }
-}
+pub type AddrR = GenR<u32, Addr>;
pub struct AddrW<'a> {
w: &'a mut W,
}
+
impl<'a> AddrW<'a> {
- pub unsafe fn bits(self, v: u32) -> &'a mut W {
- // Address must be 32-bit aligned. cf §32.8.7.2 of SAMD21 data
- // sheet.
- debug_assert!(v.trailing_zeros() >= 2);
- self.w.bits = v;
- self.w
+ pub unsafe fn bits(self, bits: u32) -> &'a mut W {
+ self.w.bits(bits)
}
-
- // TODO: "safe" method take a pointer instead of raw u32
}