From 48bb15cc0edabd3469154c689d16dc791bed0db8 Mon Sep 17 00:00:00 2001 From: Per Lindgren <per.lindgren@ltu.se> Date: Sun, 6 Jan 2019 23:45:39 +0100 Subject: [PATCH] bare6 wip --- .vscode/launch.json | 84 ++++++++++++++++- .vscode/tasks.json | 12 +++ examples/bare5.rs | 45 +++++---- examples/bare6.rs | 224 ++++++++++++++++++++++++++++++++++++++++++++ examples/device.rs | 7 -- examples/itm.rs | 7 +- 6 files changed, 342 insertions(+), 37 deletions(-) create mode 100644 examples/bare6.rs diff --git a/.vscode/launch.json b/.vscode/launch.json index e793d8c..56464e7 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -352,7 +352,64 @@ "type": "cortex-debug", "request": "launch", "servertype": "openocd", - "name": "c bare6 84Mhz", + "name": "bare6 (debug) 16Mhz", + "preLaunchTask": "cargo build --example bare6 --features stm32f4", + "executable": "./target/thumbv7em-none-eabihf/debug/examples/bare6", + "configFiles": [ + "interface/stlink.cfg", + "target/stm32f4x.cfg" + ], + "postLaunchCommands": [ + "monitor reset halt" + ], + "swoConfig": { + "enabled": true, + "cpuFrequency": 16000000, + "swoFrequency": 2000000, // you may try 1000000 if not working + "source": "probe", + "decoders": [ + { + "type": "console", + "label": "ITM", + "port": 0 + } + ] + }, + "cwd": "${workspaceRoot}" + }, + { + "type": "cortex-debug", + "request": "launch", + "servertype": "openocd", + "name": "bare6 (debug) 64Mhz", + "executable": "./target/thumbv7em-none-eabihf/debug/examples/bare6", + "configFiles": [ + "interface/stlink.cfg", + "target/stm32f4x.cfg" + ], + "postLaunchCommands": [ + "monitor reset init" + ], + "swoConfig": { + "enabled": true, + "cpuFrequency": 64000000, + "swoFrequency": 2000000, // you may try 1000000 if not working + "source": "probe", + "decoders": [ + { + "type": "console", + "label": "ITM", + "port": 0 + } + ] + }, + "cwd": "${workspaceRoot}" + }, + { + "type": "cortex-debug", + "request": "launch", + "servertype": "openocd", + "name": "bare6 (debug) 84Mhz", "executable": "./target/thumbv7em-none-eabihf/debug/examples/bare6", "configFiles": [ "interface/stlink.cfg", @@ -366,6 +423,31 @@ "cpuFrequency": 84000000, "swoFrequency": 2000000, // you may try 1000000 if not working "source": "probe", + "decoders": [ + { + "type": "console", + "label": "ITM", + "port": 0 + } + ] + }, + "cwd": "${workspaceRoot}" + }, + { + "type": "cortex-debug", + "request": "launch", + "servertype": "openocd", + "name": "bare7 (debug) 16Mhz", + "executable": "./target/thumbv7em-none-eabihf/debug/examples/bare7", + "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", diff --git a/.vscode/tasks.json b/.vscode/tasks.json index acffa43..841b615 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -183,5 +183,17 @@ "isDefault": true } }, + { + "type": "shell", + "label": "cargo build --example bare6 --features stm32f4", + "command": "cargo build --example bare6 --features stm32f4", + "problemMatcher": [ + "$rustc" + ], + "group": { + "kind": "build", + "isDefault": true + } + }, ] } \ No newline at end of file diff --git a/examples/bare5.rs b/examples/bare5.rs index d1a67f0..b55ee6b 100644 --- a/examples/bare5.rs +++ b/examples/bare5.rs @@ -136,25 +136,25 @@ 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); - - // if << is used, your code will panic in dev, but not in release mode - // t.modify(32, 3, 1); +// 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); + +// if << is used, your code will panic in dev, but not in release mode +// t.modify(32, 3, 1); //} // system startup, can be hidden from the user @@ -163,7 +163,6 @@ 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 idle(rcc, gpioa); loop {} @@ -227,9 +226,9 @@ fn idle(rcc: &mut RCC, gpioa: &mut GPIOA) { // // Discussion: // As with algebraic operations, defalut semantics differ in between -// debug/dev and release builds. E.g., debug << rhs is checked, rhs must be less +// debug/dev and release builds. E.g., debug << rhs is checked, rhs must be less // than 32 (for 32 bit datatypes). -// +// // Notice, over-shifting (where bits are spilled) is always considered legal, // its just the shift amuount that is checked. -// There are explicit unchecked versions available if so wanted. \ No newline at end of file +// There are explicit unchecked versions available if so wanted. diff --git a/examples/bare6.rs b/examples/bare6.rs new file mode 100644 index 0000000..f2d6f75 --- /dev/null +++ b/examples/bare6.rs @@ -0,0 +1,224 @@ +//! bare6.rs +//! +//! Clocking +//! +//! What it covers: +//! - setting the clock via script (again) +//! - routing the clock to a PIN for monitoring by an oscilloscope +//! - changing the clock using Rust code +//! + +// #![feature(used)] +// #![no_std] + +// extern crate f4; +// extern crate stm32f40x; + +// #[macro_use] +// extern crate cortex_m_debug; +// use f4::clock; +// use f4::prelude::*; +// use stm32f40x::{DWT, FLASH, GPIOA, GPIOC, RCC}; + +#![no_main] +#![no_std] +#![feature(uniform_paths)] + +extern crate panic_halt; + +use cortex_m::{iprint, iprintln, peripheral::itm::Stim, peripheral::syst::SystClkSource}; +use cortex_m_rt::entry; + +// use cortex_m_semihosting::hprintln; +use stm32f4::stm32f411; +use stm32f411::{DWT, GPIOA, NVIC, /* interrupt, Peripherals, Interrupt, ITM, */ RCC}; + +#[entry] +fn main() -> ! { + let p = stm32f411::Peripherals::take().unwrap(); + let mut c = stm32f411::CorePeripherals::take().unwrap(); + + //p.GPIOA.odr.write(|w| w.bits(1)); + + //let stim = &mut p. + + let stim = &mut c.ITM.stim[0]; + iprintln!(stim, "Hello, bare6!"); + + // // let dwt = unsafe { &mut *DWT.get() }; // get the reference to DWD in memory + // // 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 + // // let gpioc = unsafe { &mut *GPIOC.get() }; // get the reference to GPIOC in memory + // // let flash = unsafe { &mut *FLASH.get() }; // get the reference to FLASH in memory + + // p.DWT.enable_cycle_counter(); + // // clock_out(rcc, gpioc); + // // //clock::set_84_mhz(rcc, flash); + idle(stim, c.DWT, p.RCC, p.GPIOA); + + loop {} +} + +// // user application +fn idle(stim: &mut Stim, dwt: DWT, rcc: RCC, gpioa: GPIOA) { + iprintln!(stim, "idle"); + + // power on GPIOA, RM0368 6.3.11 + rcc.ahb1enr.modify(|_, w| w.gpioaen().set_bit()); + + // configure PA5 as output, RM0368 8.4.1 + gpioa.moder.modify(|_, w| w.moder5().bits(1)); + + // at 16 Mhz, 8000_0000 cycles = period 0.5s + // at 64 Mhz, 8000_0000 cycles = period 0.125s + let cycles = 8000_0000; + loop { + // ipln!("led on"); + // set PA5 high, RM0368 8.4.7 + gpioa.bsrr.write(|w| w.bs5().set_bit()); + wait_cycles(&dwt, cycles); + + // ipln!("led off"); + // set PA5 low, RM0368 8.4.7 + gpioa.bsrr.write(|w| w.br5().set_bit()); + wait_cycles(&dwt, cycles); + } +} + +// uses the DWT.CYCNT +// doc: ARM trm_100166_0001_00_en.pdf, chapter 9.2 +// we use the `cortex-m` abstraction, as re-exported by the stm32f40x +fn wait_cycles(dwt: &DWT, nr_cycles: u32) { + let t = dwt.cyccnt.read().wrapping_add(nr_cycles); + while (dwt.cyccnt.read().wrapping_sub(t) as i32) < 0 {} +} + +// see the Reference Manual RM0368 (www.st.com/resource/en/reference_manual/dm00096844.pdf) +// rcc, chapter 6 +// gpio, chapter 8 +// fn clock_out(rcc: &mut RCC, gpioc: &mut GPIOC) { +// // output MCO2 to pin PC9 + +// // mco2 : SYSCLK = 0b00 +// // mcopre : divide by 4 = 0b110 +// rcc.cfgr +// .modify(|_, w| unsafe { w.mco2().bits(0b00).mco2pre().bits(0b110) }); + +// // power on GPIOC, RM0368 6.3.11 +// rcc.ahb1enr.modify(|_, w| w.gpiocen().set_bit()); + +// // MCO_2 alternate function AF0, STM32F401xD STM32F401xE data sheet +// // table 9 +// // AF0, gpioc reset value = AF0 + +// // configure PC9 as alternate function 0b10, RM0368 6.2.10 +// gpioc.moder.modify(|_, w| unsafe { w.moder9().bits(0b10) }); + +// // otyper reset state push/pull, in reset state (don't need to change) + +// // ospeedr 0b11 = high speed +// gpioc +// .ospeedr +// .modify(|_, w| unsafe { w.ospeedr9().bits(0b11) }); +// } + +// 1. Compile and run the example, in 16Mhz +// The processor SYSCLK defaults to HCI 16Mhz +// (this is what you get after a `monitor reset halt`). +// +// confirm that your ITM dump traces the init, idle and led on/off +// make sure your TPIU is set to a system clock at 16Mhz +// +// you may use either ITM tracing using ITM dump or internally in +// vscode using the new "cortex debug" plugin +// +// what is the frequency of blinking +// ** your answer here ** +// +// commit your answers (bare6_1) +// +// 2. now connect an oscilloscope to PC9, which is set to +// output the MCO2 +// +// what is the frequency of MCO2 read by the oscilloscope +// ** your answer here ** +// +// compute the value of SYSCLK based on the oscilloscope reading +// ** your answer here ** +// +// what is the peak to peak reading of the signal +// ** your answer here ** +// +// make a folder called "pictures" in your git project +// make a screen dump or photo of the oscilloscope output +// save the the picture as "bare_6_16mhz_high_speed" +// +// commit your answaaasers (bare6_2) +// +// 3. now run the example in 64Mz +// you can do that by issuing a `monitor reset init` +// which reprograms SYSCLK to 4*HCI +// (make sure you have the latest openocd v 0.10) +// +// confirm that your ITM dump traces the init, idle and led on/off +// (make sure your TPIU is set to a system clock at 64Mhz) +// +// what is the frequency of blinking +// ** your answer here ** +// +// commit your answers (bare6_3) +// +// 4. repeat the experiment 2 +// what is the frequency of MCO2 read by the oscilloscope +// ** your answer here ** +// +// compute the value of SYSCLK based on the oscilloscope reading +// ** your answer here ** +// what is the peak to peak reading of the signal +// +// ** your answer here ** +// +// make a screen dump or photo of the oscilloscope output +// save the the picture as "bare_6_64mhz_high_speed" +// +// commit your answers (bare6_4) +// +// 5. now we will put the MCU in 84MHz using the function +// clock::set_84_mhz(rcc, flash); +// +// this function is part of the `f4` support crate (by Johonnes Sjölund) +// besides `rcc` (for clocking) it takes `flash` as a parameter to set +// up correct latency (wait states) for the flash memory (where our +// program typically resides). This is required since the flash cannot +// operate at the full 84MHz, so the MCU has to wait for the memory. +// +// repeat the experiment 2. +// what is the frequency of MCO2 read by the oscilloscope +// ** your answer here ** +// +// compute the value of SYSCLK based on the oscilloscope reading +// ** your answer here ** +// what is the peak to peak reading of the signal +// +// ** your answer here ** +// +// make a screen dump or photo of the oscilloscope output +// save the the picture as "bare_6_84mhz_high_speed" +// +// commit your answers (bare6_5) +// +// 6. now reprogram the PC9 to be "Low Speed", and re-run at 84Mz +// +// did the frequency change in comparison to assignment 5. +// ** your answer here ** +// +// what is the peak to peak reading of the signal +// ** your answer here ** +// +// why does it differ? +// ** your answer here ** +// +// make a screen dump or photo of the oscilloscope output +// save the the picture as "bare_6_84mhz_low_speed" +// +// commit your answers (bare6_6) diff --git a/examples/device.rs b/examples/device.rs index baf5ca2..f78e482 100644 --- a/examples/device.rs +++ b/examples/device.rs @@ -12,13 +12,6 @@ //! //! [`stm32f103xx`]: https://crates.io/crates/stm32f103xx //! -//! ``` -//! $ edit Cargo.toml && tail $_ -//! [dependencies.stm32f103xx] -//! features = ["rt"] -//! version = "0.10.0" -//! ``` -//! //! --- #![no_main] diff --git a/examples/itm.rs b/examples/itm.rs index ab3e188..b4c9401 100644 --- a/examples/itm.rs +++ b/examples/itm.rs @@ -1,12 +1,7 @@ -//! Sends "Hello, world!" through the ITM port 0 +//! Sends "Hello, agian!" over the ITM port 0 //! //! ITM is much faster than semihosting. Like 4 orders of magnitude or so. //! -//! **NOTE** Cortex-M0 chips don't support ITM. -//! -//! You'll have to connect the microcontroller's SWO pin to the SWD interface. Note that some -//! development boards don't provide this option. -//! //! You'll need [`itmdump`] to receive the message on the host plus you'll need to uncomment two //! `monitor` commands in the `.gdbinit` file. //! -- GitLab