From f380c731484f65918be16454b121702ff771329e Mon Sep 17 00:00:00 2001
From: Andrey Zgarbul <zgarbul.andrey@gmail.com>
Date: Sun, 12 Jan 2020 18:07:09 +0300
Subject: [PATCH] Add RegisterBlock trait

---
 CHANGELOG.md               | 3 +++
 src/generate/generic.rs    | 9 +++++++++
 src/generate/peripheral.rs | 9 +++++++++
 3 files changed, 21 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 118abdf2..9ca78c2e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
 
 ### Added
 
+- RegisterBlock trait (like `Deref`, but don't require `self` instance,
+  only for memory fixed peripherals)
+
 - Support for registers with alternateGroup
 
 - New `-m` switch generates a `mod.rs` file instead of `lib.rs`, which can
diff --git a/src/generate/generic.rs b/src/generate/generic.rs
index b2863807..3488e1b5 100644
--- a/src/generate/generic.rs
+++ b/src/generate/generic.rs
@@ -1,5 +1,14 @@
 use core::marker;
 
+///This trait allows to get raw pointer on derived peripheral
+///as block of registers of base peripheral (like unsafe `Deref`)
+pub trait RegisterBlock {
+    ///Type of RegisterBlock of base peripheral
+    type RB;
+    ///Take peripheral address as raw pointer
+    fn rb() -> *const Self::RB;
+}
+
 /// Raw register type
 pub trait RegisterSpec {
     /// Raw register type (`u8`, `u16`, `u32`, ...).
diff --git a/src/generate/peripheral.rs b/src/generate/peripheral.rs
index 6dd02787..8d0dcb15 100644
--- a/src/generate/peripheral.rs
+++ b/src/generate/peripheral.rs
@@ -79,6 +79,15 @@ pub fn render(
             }
         }
 
+        impl crate::RegisterBlock for #name_pc {
+            type RB = #base::RegisterBlock;
+
+            #[inline(always)]
+            fn rb() -> *const Self::RB {
+                #name_pc::ptr()
+            }
+        }
+
         impl core::fmt::Debug for #name_pc {
             fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
                 f.debug_struct(#name_str).finish()