Skip to content
Snippets Groups Projects
Commit 9474be3d authored by Per's avatar Per
Browse files

14uA stop mode

parent 16d62134
No related branches found
No related tags found
No related merge requests found
......@@ -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"
......@@ -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}"
},
]
......
......@@ -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
......@@ -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);
......
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. */
......
# 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
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment