From 1efbfa56ca8aa07477e5092a2794c1bceedc38a1 Mon Sep 17 00:00:00 2001
From: 97gushan <97gustavh@gmail.com>
Date: Wed, 1 Apr 2020 10:42:44 +0200
Subject: [PATCH] bare5_2

---
 examples/bare5.rs | 67 ++++++++++++++++++++++++++++-------------------
 1 file changed, 40 insertions(+), 27 deletions(-)

diff --git a/examples/bare5.rs b/examples/bare5.rs
index 9282a87..32554e3 100644
--- a/examples/bare5.rs
+++ b/examples/bare5.rs
@@ -13,6 +13,8 @@ extern crate panic_halt;
 
 extern crate cortex_m;
 use cortex_m_rt::entry;
+use cortex_m_semihosting::hprintln;
+
 
 // C like API...
 mod stm32f40x {
@@ -57,12 +59,17 @@ mod stm32f40x {
     // width  (field width)
     // value  (new value that the field should take)
     //
-    // impl VolatileCell<u32> {
-    //     #[inline(always)]
-    //     pub fn modify(&self, offset: u8, width: u8, value: u32) {
-    //         // your code here
-    //     }
-    // }
+    impl VolatileCell<u32> {
+        #[inline(always)]
+        pub fn modify(&self, offset: u8, width: u8, value: u32) {
+            let mask: u32 = (1 << width) - 1;
+            let masked_value = value & mask;
+
+            let r = self.read() & !(mask << offset);
+
+            self.write(r | masked_value << offset);
+        }
+    }
 
     #[repr(C)]
     #[allow(non_snake_case)]
@@ -141,27 +148,29 @@ fn wait(i: u32) {
 }
 
 // simple test of Your `modify`
-//fn test() {
-// let t:VolatileCell<u32> = unsafe {  core::mem::uninitialized() };
-// t.write(0);
-// assert!(t.read() == 0);
-// t.modify(3, 3, 0b10101);
-// //
-// //     10101
-// //    ..0111000
-// //    ---------
-// //    000101000
-// assert!(t.read() == 0b101 << 3);
-// t.modify(4, 3, 0b10001);
-// //    000101000
-// //      111
-// //      001
-// //    000011000
-// assert!(t.read() == 0b011 << 3);
+fn test() {
+    let t:VolatileCell<u32> = unsafe {  core::mem::uninitialized() };
+    t.write(0);
+    assert!(t.read() == 0);
+    t.modify(3, 3, 0b10101);
+    //
+    //     10101
+    //    ..0111000
+    //    ---------
+    //    000101000
+    hprintln!("{:?}", t.read()).unwrap();
+    hprintln!("{:?}", 0b101 << 3);
+    assert!(t.read() == 0b101 << 3);
+    t.modify(4, 3, 0b10001);
+    //    000101000
+    //      111
+    //      001
+    //    000011000
+    assert!(t.read() == 0b011 << 3);
 
 // if << is used, your code will panic in dev (debug), but not in release mode
 // t.modify(32, 3, 1);
-//}
+}
 
 // system startup, can be hidden from the user
 #[entry]
@@ -169,7 +178,7 @@ fn main() -> ! {
     let rcc = unsafe { &mut *RCC::get() }; // get the reference to RCC in memory
     let gpioa = unsafe { &mut *GPIOA::get() }; // get the reference to GPIOA in memory
 
-    // test(); // uncomment to run test
+    test(); // uncomment to run test
     idle(rcc, gpioa);
     loop {
         continue;
@@ -192,7 +201,9 @@ fn idle(rcc: &mut RCC, gpioa: &mut GPIOA) {
 
         // alternatively to set the bit high we can
         // read the value, or with PA5 (bit 5) and write back
-        gpioa.ODR.write(gpioa.ODR.read() | (1 << 5));
+        // gpioa.ODR.write(gpioa.ODR.read() | (1 << 5));
+
+        gpioa.ODR.modify(5, 1, 1);
 
         wait(10_000);
 
@@ -201,7 +212,9 @@ fn idle(rcc: &mut RCC, gpioa: &mut GPIOA) {
 
         // alternatively to clear the bit we can
         // read the value, mask out PA5 (bit 5) and write back
-        gpioa.ODR.write(gpioa.ODR.read() & !(1 << 5));
+        // gpioa.ODR.write(gpioa.ODR.read() & !(1 << 5));
+        gpioa.ODR.modify(5, 1, 0);
+
         wait(10_000);
     }
 }
-- 
GitLab