From 9474be3d7ef14844aa3fd2732a75a278084512ba Mon Sep 17 00:00:00 2001
From: Per <Per Lindgren>
Date: Thu, 28 Jun 2018 10:58:58 +0200
Subject: [PATCH] 14uA stop mode

---
 .cargo/config          |   2 +-
 .vscode/launch.json    | 193 +--------------
 Cargo.toml             |   9 +-
 examples/sleep_stop.rs | 537 ++++++++++++++++++++++++++++-------------
 memory.x               |   4 +-
 stm32f1x_per.cfg       |  80 ++++++
 6 files changed, 470 insertions(+), 355 deletions(-)
 create mode 100644 stm32f1x_per.cfg

diff --git a/.cargo/config b/.cargo/config
index 4847ccc..6f42214 100644
--- a/.cargo/config
+++ b/.cargo/config
@@ -49,4 +49,4 @@ rustflags = [
 [build]
 # (a) you also need to comment out the other two `link-arg` lines. But note that as of v0.6.0 LLD
 # has a bug where it mislinks FFI calls and they up crashing the program at runtime[build]
-target = "thumbv7em-none-eabihf"
+target = "thumbv7m-none-eabi"
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 01a0f4b..2c63a8b 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -4,143 +4,15 @@
     // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
     "version": "0.2.0",
     "configurations": [
-        {
-            "type": "cortex-debug",
-            "request": "launch",
-            "servertype": "openocd",
-            "name": "hello",
-            "executable": "./target/thumbv7em-none-eabihf/debug/examples/hello",
-            "configFiles": [
-                "interface/stlink.cfg",
-                "target/stm32f4x.cfg"
-            ],
-            "swoConfig": {
-                "enabled": true,
-                "cpuFrequency": 16000000,
-                "swoFrequency": 2000000, // you may try 1000000 if not working
-                "source": "probe",
-                "decoders": [
-                    {
-                        "type": "console",
-                        "label": "Name",
-                        "port": 0
-                    }
-                ],
-            },
-            "postLaunchCommands": [
-                "monitor arm semihosting enable",
-            ],
-            "cwd": "${workspaceRoot}",
-        },
-        {
-            "type": "cortex-debug",
-            "request": "launch",
-            "servertype": "openocd",
-            "name": "hello (release)",
-            "executable": "./target/thumbv7em-none-eabihf/release/examples/hello",
-            "configFiles": [
-                "interface/stlink.cfg",
-                "target/stm32f4x.cfg"
-            ],
-            "swoConfig": {
-                "enabled": true,
-                "cpuFrequency": 16000000,
-                "swoFrequency": 2000000, // you may try 1000000 if not working
-                "source": "probe",
-                "decoders": [
-                    {
-                        "type": "console",
-                        "label": "Name",
-                        "port": 0
-                    }
-                ]
-            },
-            "cwd": "${workspaceRoot}",
-        },
-        {
-            "type": "cortex-debug",
-            "request": "launch",
-            "servertype": "openocd",
-            "name": "stop",
-            "executable": "./target/thumbv7em-none-eabihf/debug/examples/stop",
-            "configFiles": [
-                "interface/stlink.cfg",
-                "target/stm32f4x.cfg"
-            ],
-            "swoConfig": {
-                "enabled": true,
-                "cpuFrequency": 8000000,
-                "swoFrequency": 2000000, // you may try 1000000 if not working
-                "source": "probe",
-                "decoders": [
-                    {
-                        "type": "console",
-                        "label": "Name",
-                        "port": 0
-                    }
-                ]
-            },
-            "cwd": "${workspaceRoot}"
-        },
-        {
-            "type": "cortex-debug",
-            "request": "launch",
-            "servertype": "openocd",
-            "name": "sleep",
-            "executable": "./target/thumbv7em-none-eabihf/debug/examples/sleep",
-            "configFiles": [
-                "interface/stlink.cfg",
-                "target/stm32f4x.cfg"
-            ],
-            "swoConfig": {
-                "enabled": true,
-                "cpuFrequency": 8000000,
-                "swoFrequency": 2000000, // you may try 1000000 if not working
-                "source": "probe",
-                "decoders": [
-                    {
-                        "type": "console",
-                        "label": "Name",
-                        "port": 0
-                    }
-                ]
-            },
-            "cwd": "${workspaceRoot}"
-        },
         {
             "type": "cortex-debug",
             "request": "launch",
             "servertype": "openocd",
             "name": "sleep_stop",
-            "executable": "./target/thumbv7em-none-eabihf/debug/examples/sleep_stop",
-            "configFiles": [
-                "interface/stlink.cfg",
-                "target/stm32f4x.cfg"
-            ],
-            "swoConfig": {
-                "enabled": true,
-                "cpuFrequency": 8000000,
-                "swoFrequency": 2000000, // you may try 1000000 if not working
-                "source": "probe",
-                "decoders": [
-                    {
-                        "type": "console",
-                        "label": "Name",
-                        "port": 0
-                    }
-                ]
-            },
-            "cwd": "${workspaceRoot}"
-        },
-        {
-            "type": "cortex-debug",
-            "request": "launch",
-            "servertype": "openocd",
-            "name": "sleep (release)",
-            "executable": "./target/thumbv7em-none-eabihf/release/examples/sleep",
+            "executable": "./target/thumbv7m-none-eabi/debug/examples/sleep_stop",
             "configFiles": [
                 "interface/stlink.cfg",
-                "target/stm32f4x.cfg"
+                "target/stm32f1x.cfg"
             ],
             "swoConfig": {
                 "enabled": true,
@@ -153,32 +25,7 @@
                         "label": "Name",
                         "port": 0
                     }
-                ]
-            },
-            "cwd": "${workspaceRoot}"
-        },
-        {
-            "type": "cortex-debug",
-            "request": "launch",
-            "servertype": "openocd",
-            "name": "standby",
-            "executable": "./target/thumbv7em-none-eabihf/debug/examples/standby",
-            "configFiles": [
-                "interface/stlink.cfg",
-                "target/stm32f4x.cfg"
-            ],
-            "swoConfig": {
-                "enabled": true,
-                "cpuFrequency": 8000000,
-                "swoFrequency": 2000000, // you may try 1000000 if not working
-                "source": "probe",
-                "decoders": [
-                    {
-                        "type": "console",
-                        "label": "Name",
-                        "port": 0
-                    }
-                ]
+                ],
             },
             "cwd": "${workspaceRoot}"
         },
@@ -186,11 +33,11 @@
             "type": "cortex-debug",
             "request": "launch",
             "servertype": "openocd",
-            "name": "standby (release)",
-            "executable": "./target/thumbv7em-none-eabihf/release/examples/standby",
+            "name": "sleep_stop (stm32f1x_per)",
+            "executable": "./target/thumbv7m-none-eabi/debug/examples/sleep_stop",
             "configFiles": [
                 "interface/stlink.cfg",
-                "target/stm32f4x.cfg"
+                "stm32f1x_per.cfg"
             ],
             "swoConfig": {
                 "enabled": true,
@@ -203,33 +50,19 @@
                         "label": "Name",
                         "port": 0
                     }
-                ]
+                ],
             },
             "cwd": "${workspaceRoot}"
         },
         {
             "type": "cortex-debug",
             "request": "launch",
-            "servertype": "openocd",
-            "name": "panic",
-            "executable": "./target/thumbv7em-none-eabihf/debug/examples/panic",
-            "configFiles": [
-                "interface/stlink.cfg",
-                "target/stm32f4x.cfg"
-            ],
-            "swoConfig": {
-                "enabled": true,
-                "cpuFrequency": 8000000,
-                "swoFrequency": 2000000, // you may try 1000000 if not working
-                "source": "probe",
-                "decoders": [
-                    {
-                        "type": "console",
-                        "label": "Name",
-                        "port": 0
-                    }
-                ]
-            },
+            "servertype": "bmp",
+            "name": "sleep_stop (bmp)",
+            "executable": "./target/thumbv7m-none-eabi/debug/examples/sleep_stop",
+            "device": "STM32F103RB",
+            "BMPGDBSerialPort": "/dev/ttyACM1",
+            "targetId": 1,
             "cwd": "${workspaceRoot}"
         },
     ]
diff --git a/Cargo.toml b/Cargo.toml
index 8f77950..ee3f134 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,10 +11,10 @@
 # will likely look very different (and much more reasonable)
 
 [package]
-name = "cortex-m-quickstart"
+name = "low-power-stm32f103"
 version = "0.3.1"
 authors = ["Per Lindgren <per.lindgren@ltu.se>"]
-description = "Low Power Experiments on the Nucleo 64 stm32f401re"
+description = "Low Power Experiments on the Nucleo 64 stm32f103"
 keywords = ["arm", "cortex-m", "template"]
 categories = ["embedded", "no-std"]
 license = "MIT OR Apache-2.0"
@@ -38,9 +38,8 @@ version = "0.2.0"
 [dependencies.panic-semihosting]
 version = "0.3.0"
 
-[dependencies.stm32f40x]
-path = "../STM32F40x"
+[dependencies.stm32f103xx]
 features = ["rt"]
-version = "0.3.0"
+version = "0.10.0"
 
 #panic = "abort"
\ No newline at end of file
diff --git a/examples/sleep_stop.rs b/examples/sleep_stop.rs
index 3e5c5cb..fbeb256 100644
--- a/examples/sleep_stop.rs
+++ b/examples/sleep_stop.rs
@@ -6,8 +6,8 @@
 extern crate cortex_m;
 
 #[macro_use(interrupt)]
-extern crate stm32f40x;
-use stm32f40x::Interrupt;
+extern crate stm32f103xx;
+use stm32f103xx::Interrupt;
 
 #[macro_use(entry, exception)]
 extern crate cortex_m_rt as rt;
@@ -18,43 +18,16 @@ use rt::ExceptionFrame;
 
 use cortex_m::peripheral::Peripherals;
 
-fn analog_input() {
-    #[allow(non_snake_case)]
-    let GPIOC = unsafe { &*stm32f40x::GPIOC::ptr() };
-    #[allow(non_snake_case)]
-    let GPIOD = unsafe { &*stm32f40x::GPIOD::ptr() };
-    #[allow(non_snake_case)]
-    let GPIOE = unsafe { &*stm32f40x::GPIOE::ptr() };
-    // #[allow(non_snake_case)]
-    // let GPIOF = unsafe { &*stm32f40x::GPIOF::ptr() };
-    // #[allow(non_snake_case)]
-    // let GPIOG = unsafe { &*stm32f40x::GPIOG::ptr() };
-    // #[allow(non_snake_case)]
-    // let GPIOH = unsafe { &*stm32f40x::GPIOH::ptr() };
-    // #[allow(non_snake_case)]
-    // let GPIOI = unsafe { &*stm32f40x::GPIOI::ptr() };
-    let r1 = GPIOC.moder.read().bits();
-    GPIOC.moder.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); // analog mode
-    GPIOD.moder.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); // analog mode
-    GPIOE.moder.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); // analog mode
-                                                           // GPIOF.moder.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); // analog mode
-                                                           // GPIOG.moder.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); // analog mode
-                                                           // GPIOH.moder.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); // analog mode
-                                                           // GPIOI.moder.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); // analog mode
-
-    let r2 = GPIOC.moder.read().bits();
-    // asm::bkpt();
-}
-
 // set the MCU in debug sleepdeep mode on WFI/WFE
 // debugging is possible even if sleeping
 fn dbg_enable() {
-    let dbg = unsafe { &*stm32f40x::DBG::ptr() };
-    #[allow(non_snake_case)]
-    let GPIOA = unsafe { &*stm32f40x::GPIOA::ptr() };
-    #[allow(non_snake_case)]
-    let GPIOB = unsafe { &*stm32f40x::GPIOB::ptr() };
-    dbg.dbgmcu_cr.modify(|_, w| {
+    let dbg = unsafe { &*stm32f103xx::DBG::ptr() };
+    let afio = unsafe { &*stm32f103xx::AFIO::ptr() };
+    // #[allow(non_snake_case)]
+    // let GPIOA = unsafe { &*stm32f40x::GPIOA::ptr() };
+    // #[allow(non_snake_case)]
+    // let GPIOB = unsafe { &*stm32f40x::GPIOB::ptr() };
+    dbg.cr.modify(|_, w| {
         w.dbg_sleep()
             .set_bit()
             .dbg_stop()
@@ -64,11 +37,14 @@ fn dbg_enable() {
             .trace_ioen()
             .set_bit()
     });
-    GPIOA.moder.reset();
-    GPIOA.pupdr.reset();
 
-    GPIOB.moder.reset();
-    GPIOB.pupdr.reset();
+    // 31.4.2, table 220
+    // afio.mapr.modify(|_, w| unsafe { w.swj_cfg().bits(0b000) }); // all debugging
+    // GPIOA.moder.reset();
+    // GPIOA.pupdr.reset();
+
+    // GPIOB.moder.reset();
+    // GPIOB.pupdr.reset();
 }
 
 // set the MCU in true sleepdeep mode on WFI/WFE
@@ -76,172 +52,399 @@ fn dbg_enable() {
 
 fn dbg_disable() {
     #[allow(non_snake_case)]
-    let DBG = unsafe { &*stm32f40x::DBG::ptr() };
+    let DBG = unsafe { &*stm32f103xx::DBG::ptr() };
+    let afio = unsafe { &*stm32f103xx::AFIO::ptr() };
     #[allow(non_snake_case)]
-    let GPIOA = unsafe { &*stm32f40x::GPIOA::ptr() };
+    let GPIOA = unsafe { &*stm32f103xx::GPIOA::ptr() };
     #[allow(non_snake_case)]
-    let GPIOB = unsafe { &*stm32f40x::GPIOB::ptr() };
-    asm::nop();
-    DBG.dbgmcu_cr.modify(|_, w| {
-        w.dbg_sleep()
-            .clear_bit()
-            .dbg_stop()
-            .clear_bit()
-            .dbg_standby()
-            .clear_bit()
-            .trace_ioen()
-            .clear_bit()
-    });
+    let GPIOB = unsafe { &*stm32f103xx::GPIOB::ptr() };
+    #[allow(non_snake_case)]
+    let GPIOC = unsafe { &*stm32f103xx::GPIOC::ptr() };
     // set all gpio to analog input
-    // let _a_moder_ = GPIOA.moder.read().bits();
-    // let _b_moder_ = GPIOB.moder.read().bits();
+    let _a_crl_ = GPIOA.crl.read().bits();
+    let _a_crh_ = GPIOA.crh.read().bits();
+    // let _b_moder_ = GPIOB.crl.read().bits();
     // let _a_pupdr_ = GPIOA.pupdr.read().bits();
     // let _b_pupdr_ = GPIOB.pupdr.read().bits();
 
     // 0.142 mA without manipulating GPIO/GPIOB
+    let v = GPIOA.crl.read().bits();
+
+    // GPIOA.crl.write(|w| unsafe { w.bits(0x0) }); // PA l, analog
+    // GPIOA.crl.modify(|_, w| w.cnf1().bits(0b10)); // PA1 input pull up/down
+
+    // set PA0, PA2-7, to analog mode
+    GPIOA.crl.modify(|_, w| {
+        w.cnf0()
+            .bits(0b00)
+            .cnf2()
+            .bits(0b00)
+            .cnf3()
+            .bits(0b00)
+            .cnf4()
+            .bits(0b00)
+            .cnf5()
+            .bits(0b00)
+            .cnf6()
+            .bits(0b00)
+            .cnf7()
+            .bits(0b00)
+    });
 
-    GPIOA.moder.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); // PA, analog
-    GPIOA.moder.modify(|_, w| w.moder1().input_mode()); // PA1, input_mode
-    GPIOB.pupdr.write(|w| unsafe { w.bits(0) }); // PA, floating
-    GPIOA.pupdr.modify(|_, w| w.pupdr1().pull_up()); // PA1, pull up
+    // set PA8-15, to analog mode
+    GPIOA.crh.modify(|_, w| {
+        w.cnf8()
+            .bits(0b00)
+            .cnf9()
+            .bits(0b00)
+            .cnf10()
+            .bits(0b00)
+            .cnf11()
+            .bits(0b00)
+            .cnf12()
+            .bits(0b00)
+            .cnf13()
+            .bits(0b00)
+            .cnf14()
+            .bits(0b00)
+            .cnf15()
+            .bits(0b00)
+    });
 
-    GPIOB.moder.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); // PB, analog
-    GPIOB.pupdr.write(|w| unsafe { w.bits(0) }); // PB, floating
+    GPIOB.crl.modify(|_, w| {
+        w.cnf0()
+            .bits(0b00)
+            .cnf1()
+            .bits(0b00)
+            .cnf2()
+            .bits(0b00)
+            .cnf3()
+            .bits(0b00)
+            .cnf4()
+            .bits(0b00)
+            .cnf5()
+            .bits(0b00)
+            .cnf6()
+            .bits(0b00)
+            .cnf7()
+            .bits(0b00)
+    });
+
+    // set PA8-15, to analog mode
+    GPIOB.crh.modify(|_, w| {
+        w.cnf8()
+            .bits(0b00)
+            .cnf9()
+            .bits(0b00)
+            .cnf10()
+            .bits(0b00)
+            .cnf11()
+            .bits(0b00)
+            .cnf12()
+            .bits(0b00)
+            .cnf13()
+            .bits(0b00)
+            .cnf14()
+            .bits(0b00)
+            .cnf15()
+            .bits(0b00)
+    });
+
+    GPIOC.crl.modify(|_, w| {
+        w.cnf0()
+            .bits(0b00)
+            .cnf1()
+            .bits(0b00)
+            .cnf2()
+            .bits(0b00)
+            .cnf3()
+            .bits(0b00)
+            .cnf4()
+            .bits(0b00)
+            .cnf5()
+            .bits(0b00)
+            .cnf6()
+            .bits(0b00)
+            .cnf7()
+            .bits(0b00)
+    });
+
+    // set PA8-15, to analog mode
+    GPIOC.crh.modify(|_, w| {
+        w.cnf8()
+            .bits(0b00)
+            .cnf9()
+            .bits(0b00)
+            .cnf10()
+            .bits(0b00)
+            .cnf11()
+            .bits(0b00)
+            .cnf12()
+            .bits(0b00)
+            .cnf13()
+            .bits(0b00)
+            .cnf14()
+            .bits(0b00)
+            .cnf15()
+            .bits(0b00)
+    });
+
+    let vl = GPIOA.crl.read().bits();
+    let vh = GPIOA.crh.read().bits();
+    // GPIOA.crh.write(|w| unsafe { w.bits(0x0) }); // PA h, analog
+    // GPIOA.moder.modify(|_, w| w.moder1().input_mode()); // PA1, input_mode
+    // GPIOB.pupdr.write(|w| unsafe { w.bits(0) }); // PA, floating
+    // GPIOA.pupdr.modify(|_, w| w.pupdr1().pull_up()); // PA1, pull up
+
+    let _a_crl = GPIOA.crl.read().bits();
+    let _a_crh = GPIOA.crh.read().bits();
 
-    // let _a_moder = GPIOA.moder.read().bits();
-    // let _b_moder = GPIOB.moder.read().bits();
-    // let _a_pupdr = GPIOA.pupdr.read().bits();
-    // let _b_pupdr = GPIOB.pupdr.read().bits();
     asm::nop();
+
+    // let swj = afio.mapr.read().bits();
+
+    // DBG.cr.modify(|_, w| {
+    //     w.dbg_sleep()
+    //         .clear_bit()
+    //         .dbg_stop()
+    //         .clear_bit()
+    //         .dbg_standby()
+    //         .clear_bit()
+    //         .trace_ioen()
+    //         .clear_bit()
+    // });
+
+    // 31.4.2, table 220
+    // afio.mapr.modify(|_, w| unsafe { w.swj_cfg().bits(0b100) }); // no debugging
+
+    // GPIOB.moder.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); // PB, analog
+    // GPIOB.pupdr.write(|w| unsafe { w.bits(0) }); // PB, floating
 }
 
 // the program entry point is ...
 entry!(main);
-// ... this never ending function
+
+fn clock_out(rcc: &stm32f103xx::RCC, gpioa: &stm32f103xx::GPIOA) {
+    // output MCO to pin PA8
+    // mco 	: SYSCLK = 0b100, 8.2.10
+    rcc.cfgr.modify(|_, w| unsafe { w.mco().bits(0b100) });
+
+    // power on GPIOa,
+    // clock enable gpioa for clock output
+    rcc.apb2enr.modify(|_, w| w.iopaen().set_bit());
+
+    // 9.2.2
+    // PA8 50 MHz, push pull alternate function
+    gpioa
+        .crh
+        .modify(|_, w| w.mode8().output50().cnf8().alt_push());
+}
+
+// bind the EXTI1 handler
+interrupt!(EXTI1, exti1);
+
+// the exti1 interrupt implementation
+fn exti1() {
+    // dbg_enable();
+    led(10);
+    asm::bkpt();
+    // led(10);
+    // clear pending state
+    let exti = unsafe { &*stm32f103xx::EXTI::ptr() };
+    exti.pr.write(|w| w.pr1().set_bit());
+    // dbg_disable();
+}
+
+fn led(i: u8) {
+    #[allow(non_snake_case)]
+    let GPIOC = unsafe { &*stm32f103xx::GPIOC::ptr() };
+    GPIOC.crh.modify(|_, w| w.mode13().output()); // PC13 set as output
+    for _ in 0..i {
+        for _ in 0..1000 {}
+        GPIOC.bsrr.write(|w| w.br13().set_bit());
+        for _ in 0..1000 {}
+        GPIOC.bsrr.write(|w| w.bs13().set_bit());
+    }
+    GPIOC.crh.modify(|_, w| w.mode13().input()); // PC13 set as input
+}
+
 fn main() -> ! {
-    let r = stm32f40x::Peripherals::take().unwrap();
+    let r = stm32f103xx::Peripherals::take().unwrap();
     let mut p = Peripherals::take().unwrap();
 
     // enable the EXTI1 interrupt
     p.NVIC.enable(Interrupt::EXTI1);
-    // enable gpioa, gpiob
-    r.RCC.ahb1enr.modify(|_, w| {
-        w.gpioaen()
-            .set_bit()
-            .gpioben()
-            .set_bit()
-            .gpiocen()
-            .set_bit()
-            .gpioden()
-            .set_bit()
-            .gpioeen()
-            .set_bit()
-            .gpiofen()
-            .set_bit()
-    });
-    // asm::bkpt();
-    analog_input();
-    // asm::bkpt();
 
-    let mut read: u32 = 0;
+    // clock_out(&r.RCC, &r.GPIOA);
+    asm::bkpt();
 
-    // PA1 pull up
-    r.GPIOA.pupdr.modify(|r, w| w.pupdr1().pull_up());
-    #[allow(non_snake_case)]
-    let GPIOA = unsafe { &*stm32f40x::GPIOA::ptr() };
+    // PC13, led
+    // r.RCC.apb2enr.modify(|_, w| w.iopcen().set_bit()); // clock enable gpioc
+    // r.GPIOC.crh.modify(|_, w| w.mode13().output()); // PC13 set as output
 
+    // led(10);
     asm::nop();
 
-    // SYSCFG.exti1 is PAx (0000) by reset, so we don't change it
+    // clock enable gpioa, gpiob, gpioc
+    r.RCC.apb2enr.modify(|_, w| {
+        w.iopaen().set_bit().iopben().set_bit().iopcen().set_bit()
+    });
+
+    // enable alternate function
+    r.RCC.apb2enr.modify(|_, w| w.afioen().set_bit());
+    r.AFIO.exticr1.modify(|_, w| unsafe { w.exti1().bits(0) });
+
+    // input by default
+    // r.GPIOA.crl.modify(|_, w| w.cnf1().bits(0b10)); // PA1 input pull up/down
+    // r.GPIOA.odr.modify(|_, w| w.odr1().set_bit()); // PA1 input pull up
+
+    r.EXTI.ftsr.modify(|_, w| w.tr1().set_bit()); // EXTI1 trigger on falling, enable tr1
+    r.EXTI.imr.modify(|_, w| w.mr1().set_bit()); // EXTI1 interrupt mask register, enable mr1
+                                                 // r.EXTI.emr.modify(|_, w| w.mr1().set_bit()); // EXTI1 event on mask register, enabel mr1
 
-    // enbable masking of EXTI line 1
-    r.EXTI.imr.modify(|_, w| w.mr1().set_bit());
-    // trigger on falling edge
-    r.EXTI.ftsr.modify(|_, w| w.tr1().set_bit());
-    // clear triggering event
-    r.EXTI.pr.modify(|_, w| w.pr1().set_bit());
+    // test raising a software interrupt
+    // r.EXTI.swier.write(|w| w.swier1().set_bit()); // trigger sw interrupt
+
+    let pr = r.EXTI.pr.read().bits();
+
+    // r.EXTI.pr.write(|w| unsafe { w.bits(0xFFFF_FFFF) }); // clear all pending interrups/events, a bit ugly
 
     p.SCB.set_sleepdeep();
-    // enable pwr
+
+    // clock enbable pwren
     r.RCC.apb1enr.modify(|_, w| w.pwren().set_bit());
-    // set standby mode
-    // r.PWR
-    //     .cr
-    //     .write(|w| unsafe { w.bits((1 << 10) | 0x0000_8000) });
+
+    // stop mode configuration pdds clear and regulator in low power mode
     r.PWR
         .cr
-        .modify(|_, w| w.pdds().clear_bit().lpds().set_bit().fpds().set_bit());
+        .modify(|_, w| w.pdds().clear_bit().lpds().set_bit());
 
-    // r.PWR
-    //     .cr
-    //     .modify(|_, w| w.pdds().clear_bit().lpds().clear_bit());
-    // blink();
+    // regulator in run mode (on)
+    // r.PWR.cr.modify(|_, w| w.pdds().clear_bit());
 
-    // p.NVIC.set_pending(Interrupt::EXTI1);
+    let pwr = r.PWR.cr.read().bits();
+    asm::nop();
 
-    asm::bkpt();
+    dbg_disable();
+    r.EXTI.pr.write(|w| w.pr1().set_bit());
     loop {
-        asm::nop(); // put gdb breakpoint here, the MCU and gdb will detect breakpoint
-        dbg_disable();
         asm::wfi();
-        dbg_enable();
-        asm::nop(); // put gdb breakpoint here, in debug mode its caught twice
-                    // first occation (on wakeup), gdb does NOT report span correctly,
-                    // second occation, gdb DEOS report span correctly
-        asm::bkpt(); // here the MCU halt, and gdb detects the asm breakpoint
-                     // gdb continue, will catch the gdb breakpoint at "dbg_disable"
-                     // this is good as it shows that disabling and re-enabling gdb debugging works
-                     // even if the gdb communictation has been disrputed and re-estabished, nice!
-    }
-}
-// the dbg_sleep, and dbg_stop both set deos not prohibit sleep mode debugging (error?)
-// the bdg_standby set further reduces power, and prohibits debugging
-// the behavior seems not to comply with the documentation
-
-// as expected debugging release code puts the gdb breakpoint at the wrong position
-// as expected the initial breakpoint after wakeup deos not register in gdb correctly
-// also the blink loop becomes to fast to observe
-
-// unsafe version where we access GPIOA through the (raw) pointer
-fn blink() {
-    #[allow(non_snake_case)]
-    let GPIOA = unsafe { &*stm32f40x::GPIOA::ptr() };
-    // #[allow(non_snake_case)]
-    // let RCC = unsafe { &*stm32f40x::RCC::ptr() };
-    // RCC.ahb1enr.modify(|_, w| w.gpioaen().set_bit());
-    GPIOA.moder.modify(|_, w| w.moder5().output_mode());
-    for _ in 0..10 {
-        GPIOA.bsrr.write(|w| w.br5().set_bit());
-        for _ in 0..1000 {
-            asm::nop();
-        }
-
-        GPIOA.bsrr.write(|w| w.bs5().set_bit());
-        for _ in 0..1000 {
-            asm::nop();
-        }
+        //led(10);
     }
-    GPIOA.moder.modify(|_, w| w.moder5().input_mode());
-    // RCC.ahb1enr.modify(|_, w| w.gpioaen().clear_bit());
 }
 
-// bind the EXTI1 handler
-interrupt!(EXTI1, exti1);
-
-// the exti1 interrupt implementation
-fn exti1() {
-    blink(); // it will take some time so bounces are likely gone
-
-    // // let's try to "fake" access to GPIOA
-    // // let g = stm32f40x::GPIOA {
-    // //     _marker: core::marker::PhantomData, <- the field is private, so we cannot
-    // // };
-    // asm::bkpt();
-
-    // clear pending state
-    let exti = unsafe { &*stm32f40x::EXTI::ptr() };
-    exti.pr.write(|w| w.pr1().set_bit());
-}
+//             .gpiocen()
+//             .set_bit()
+//             .gpioden()
+//             .set_bit()
+//             .gpioeen()
+//             .set_bit()
+//             .gpiofen()
+//             .set_bit()
+//     });
+//     // asm::bkpt();
+//     analog_input();
+//     // asm::bkpt();
+
+//     let mut read: u32 = 0;
+
+//     // PA1 pull up
+//     r.GPIOA.pupdr.modify(|r, w| w.pupdr1().pull_up());
+//     #[allow(non_snake_case)]
+//     let GPIOA = unsafe { &*stm32f40x::GPIOA::ptr() };
+
+//     asm::nop();
+
+//     // SYSCFG.exti1 is PAx (0000) by reset, so we don't change it
+
+//     // enbable masking of EXTI line 1
+//     r.EXTI.imr.modify(|_, w| w.mr1().set_bit());
+//     // trigger on falling edge
+//     r.EXTI.ftsr.modify(|_, w| w.tr1().set_bit());
+//     // clear triggering event
+//     r.EXTI.pr.modify(|_, w| w.pr1().set_bit());
+
+//     p.SCB.set_sleepdeep();
+//     // enable pwr
+//     r.RCC.apb1enr.modify(|_, w| w.pwren().set_bit());
+//     // set standby mode
+//     // r.PWR
+//     //     .cr
+//     //     .write(|w| unsafe { w.bits((1 << 10) | 0x0000_8000) });
+//     r.PWR
+//         .cr
+//         .modify(|_, w| w.pdds().clear_bit().lpds().set_bit().fpds().set_bit());
+
+//     // r.PWR
+//     //     .cr
+//     //     .modify(|_, w| w.pdds().clear_bit().lpds().clear_bit());
+//     // blink();
+
+//     // p.NVIC.set_pending(Interrupt::EXTI1);
+
+//     asm::bkpt();
+//     loop {
+//         asm::nop(); // put gdb breakpoint here, the MCU and gdb will detect breakpoint
+//         dbg_disable();
+//         asm::wfi();
+//         dbg_enable();
+//         asm::nop(); // put gdb breakpoint here, in debug mode its caught twice
+//                     // first occation (on wakeup), gdb does NOT report span correctly,
+//                     // second occation, gdb DEOS report span correctly
+//         asm::bkpt(); // here the MCU halt, and gdb detects the asm breakpoint
+//                      // gdb continue, will catch the gdb breakpoint at "dbg_disable"
+//                      // this is good as it shows that disabling and re-enabling gdb debugging works
+//                      // even if the gdb communictation has been disrputed and re-estabished, nice!
+//     }
+// }
+// // the dbg_sleep, and dbg_stop both set deos not prohibit sleep mode debugging (error?)
+// // the bdg_standby set further reduces power, and prohibits debugging
+// // the behavior seems not to comply with the documentation
+
+// // as expected debugging release code puts the gdb breakpoint at the wrong position
+// // as expected the initial breakpoint after wakeup deos not register in gdb correctly
+// // also the blink loop becomes to fast to observe
+
+// // unsafe version where we access GPIOA through the (raw) pointer
+// fn blink() {
+//     #[allow(non_snake_case)]
+//     let GPIOA = unsafe { &*stm32f40x::GPIOA::ptr() };
+//     // #[allow(non_snake_case)]
+//     // let RCC = unsafe { &*stm32f40x::RCC::ptr() };
+//     // RCC.ahb1enr.modify(|_, w| w.gpioaen().set_bit());
+//     GPIOA.moder.modify(|_, w| w.moder5().output_mode());
+//     for _ in 0..10 {
+//         GPIOA.bsrr.write(|w| w.br5().set_bit());
+//         for _ in 0..1000 {
+//             asm::nop();
+//         }
+
+//         GPIOA.bsrr.write(|w| w.bs5().set_bit());
+//         for _ in 0..1000 {
+//             asm::nop();
+//         }
+//     }
+//     GPIOA.moder.modify(|_, w| w.moder5().input_mode());
+//     // RCC.ahb1enr.modify(|_, w| w.gpioaen().clear_bit());
+// }
+
+// // bind the EXTI1 handler
+// interrupt!(EXTI1, exti1);
+
+// // the exti1 interrupt implementation
+// fn exti1() {
+//     blink(); // it will take some time so bounces are likely gone
+
+//     // // let's try to "fake" access to GPIOA
+//     // // let g = stm32f40x::GPIOA {
+//     // //     _marker: core::marker::PhantomData, <- the field is private, so we cannot
+//     // // };
+//     // asm::bkpt();
+
+//     // clear pending state
+//     let exti = unsafe { &*stm32f40x::EXTI::ptr() };
+//     exti.pr.write(|w| w.pr1().set_bit());
+// }
 
 // define the hard fault handler
 exception!(HardFault, hard_fault);
diff --git a/memory.x b/memory.x
index f4df782..86aa62e 100644
--- a/memory.x
+++ b/memory.x
@@ -1,8 +1,8 @@
 MEMORY
 {
   /* NOTE K = KiBi = 1024 bytes */
-  FLASH : ORIGIN = 0x08000000, LENGTH = 256K
-  RAM : ORIGIN = 0x20000000, LENGTH = 40K
+  FLASH : ORIGIN = 0x08000000, LENGTH = 64K
+  RAM : ORIGIN = 0x20000000, LENGTH = 20K
 }
 
 /* This is where the call stack will be allocated. */
diff --git a/stm32f1x_per.cfg b/stm32f1x_per.cfg
new file mode 100644
index 0000000..e0e7643
--- /dev/null
+++ b/stm32f1x_per.cfg
@@ -0,0 +1,80 @@
+# script for stm32f1x family
+
+#
+# stm32 devices support both JTAG and SWD transports.
+#
+source [find target/swj-dp.tcl]
+source [find mem_helper.tcl]
+
+if { [info exists CHIPNAME] } {
+   set _CHIPNAME $CHIPNAME
+} else {
+   set _CHIPNAME stm32f1x
+}
+
+set _ENDIAN little
+
+# Work-area is a space in RAM used for flash programming
+# By default use 4kB (as found on some STM32F100s)
+if { [info exists WORKAREASIZE] } {
+   set _WORKAREASIZE $WORKAREASIZE
+} else {
+   set _WORKAREASIZE 0x1000
+}
+
+#jtag scan chain
+if { [info exists CPUTAPID] } {
+   set _CPUTAPID $CPUTAPID
+} else {
+   if { [using_jtag] } {
+      # See STM Document RM0008 Section 26.6.3
+      set _CPUTAPID 0x3ba00477
+   } {
+      # this is the SW-DP tap id not the jtag tap id
+      set _CPUTAPID 0x1ba01477
+   }
+}
+
+swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
+
+if {[using_jtag]} {
+   jtag newtap $_CHIPNAME bs -irlen 5
+}
+
+set _TARGETNAME $_CHIPNAME.cpu
+target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME
+
+$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
+
+# flash size will be probed
+set _FLASHNAME $_CHIPNAME.flash
+flash bank $_FLASHNAME stm32f1x 0x08000000 0 0 0 $_TARGETNAME
+
+# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz
+adapter_khz 1000
+
+adapter_nsrst_delay 100
+if {[using_jtag]} {
+ jtag_ntrst_delay 100
+}
+
+reset_config srst_nogate
+
+if {![using_hla]} {
+    # if srst is not fitted use SYSRESETREQ to
+    # perform a soft reset
+    cortex_m reset_config sysresetreq
+}
+
+$_TARGETNAME configure -event examine-end {
+	# DBGMCU_CR |= DBG_WWDG_STOP | DBG_IWDG_STOP |
+	#              DBG_STANDBY | DBG_STOP | DBG_SLEEP
+	# mmw 0xE0042004 0x00000307 0
+}
+
+$_TARGETNAME configure -event trace-config {
+	# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync
+	# change this value accordingly to configure trace pins
+	# assignment
+	mmw 0xE0042004 0x00000020 0
+}
-- 
GitLab